为什么我不能使用已删除或私有析构函数分配类的数组?
Why can't I allocate an array of a class with deleted or private destructor?
我最近在工作中遇到了这个问题。我正在使用的库利用参考计数对象,并实现了自己的处理方式。该实施的一部分是,每个类别的库都有一个私人驱动器。我猜想这是为了防止在库自动管理对象时堆栈上的对象(其场景图(。
无论如何,我想在堆上分配一系列这样的类,并遇到以下问题:
#include <iostream>
using namespace std;
class test
{
public:
test() {
cout << "ctor" << endl;
}
//~test() = delete; also doesnt work
private:
~test()
{
cout << "dtor" << endl;
}
};
int main()
{
//works
auto oneInstance = new test;
//doesnt work
auto manyInstances = new test[3];
}
数组分配使用GCC产生以下错误:
source_file.cpp: In function ‘int main()’:
source_file.cpp:15:5: error: ‘test::~test()’ is private
~test()
^
source_file.cpp:26:36: error: within this context
auto manyInstances = new test[3];
^
为什么要在堆上分配此类数组,为什么需要公开/可用?当仅在行之前分配单个实例时,它可以正常工作。我还尝试使用更现代的"删除"语法,但产生了相同的结果。
我不知道的新[]操作员中是否有任何魔术?
编辑:
感谢您的快速帮助。我想知道为什么此代码未两次打印" DTOR":
#include <iostream>
using namespace std;
class test
{
public:
test() {
static int allocations = 0;
++allocations;
if(allocations == 3)
{
//produce exception
throw 1;
}
cout << "ctor" << endl;
}
~test()
{
cout << "dtor" << endl;
}
};
int main()
{
//works
auto oneInstance = new test;
//doesnt work
try {
auto manyInstances = new test[3];
}
catch(...)
{
cout << "error?";
}
}
此打印:
ctor ctor dtor error?
是由于例外,new[]
的数组版本必须去调用destructor the Destructor,以先前分配的元素,当异常传播以确保异常安全。单个元素new
无需这样做。如果分配失败,它只是失败了,无需销毁任何东西。
§8.3.4新[Expr.new/20]
如果新表达创建了类类型的一系列对象,则可能调用destructor
关于您的编辑,请参阅C 17标准
的以下报价§8.17抛出异常[expr.throw/4]
如果目前没有例外,请评估没有操作数的投掷表达
std::terminate()
关于您的第二个编辑,您错过了通过new
(不是new[]
(创建的test
实例,该实例导致创建test
的第一个实例,这就是关于构造数量的混淆。
相关文章:
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 对具有动态分配的内存和析构函数的类对象的引用
- 调用析构函数以释放动态分配的内存
- C++析构函数调用两次,堆栈分配的复合对象
- 如何在析构函数中删除C++中动态分配的数组?
- 取消分配动态分配的字符数组的析构函数
- 如何将析构函数分配给指针
- 使用私有析构函数删除动态分配的对象
- 在C++中,当重新分配对象时,为什么构造函数在析构函数之前触发?
- 为什么我不能使用已删除或私有析构函数分配类的数组?
- 为什么要在释放分配给该对象的内存之前调用该对象的默认析构函数?
- 为什么在调用析构函数后仍然可以引用堆分配的对象
- 默认移动分配调用析构函数,复制分配不
- 当包含它的对象调用其析构函数时,unique_ptr是否未分配
- 类的堆分配对象是否在其作用域之后但在 C++ 中调用其析构函数之前处于活动状态
- 动态分配(堆上)的对象的析构函数是否会在返回函数中自动调用
- std::vector 调用在重新分配时无论如何都包含对象的析构函数?
- 具有受保护析构函数的类数组的动态分配
- 避免对临时、R 值析构函数进行不必要的分配
- 在C++中,如果我引用一个具有解除分配析构函数~MyClass的对象,那么超出范围的引用会调用析构函数吗