具有受保护析构函数的类数组的动态分配
Dynamic allocation of class array with protected destructor
如果我定义了一个类似的类
class A {
protected:
~A(){ }
};
然后我可以动态地分配个人以及像这样的对象阵列
A* ptr1 = new A;
A* ptr2 = new A[10];
然而,当我为这个类定义构造函数时
class A {
public:
A(){}
protected:
~A(){ }
};
然后我可以用创建单独的对象
A* ptr = new A;
但是当我尝试用动态分配对象数组时
A* ptr = new A[10];
编译器(gcc-5.1和Visual Studio 2015)开始抱怨A::~A()无法访问。
有人能解释一下吗:-
1-为什么定义构造函数和未定义构造函数的行为不同。
2-当构造函数被定义时,为什么我被允许创建单个对象,而不是对象数组。
根据C++11,§5.3.4¶17:,拒绝具有受保护析构函数的数组-new
是正确的
如果新表达式创建了一个类类型的对象或对象数组,则对分配函数、解除分配函数(12.5)和构造函数(12.1)执行访问和模糊控制。如果新表达式生成了一个类别类型的对象数组,那么对析构函数(12.4)执行访问或模糊控制。
(增加了强调;C++03,§5.3.4¶16中使用了几乎完全相同的措辞;C++14移动了一些东西,但这似乎并没有改变问题的核心-参见@Baum mit Augen的回答)
这是因为new[]
只有在构建了所有元素的情况下才成功,并且希望在其中一个costructor调用失败的情况下避免对象泄漏;因此,如果它成功地构造了前9个对象,但第10个对象由于异常而失败,那么它必须在传播异常之前销毁前9个。
请注意,如果构造函数被声明为noexcept
,那么逻辑上就不需要这个限制,但标准在这方面似乎没有任何异常。
因此,在第一种情况下,gcc在技术上是错误的,就标准而言,这也应该被拒绝,尽管我认为"道德上"的gcc做了正确的事情(因为在实践中,A
的默认构造函数不可能抛出)。
事实证明,gcc在这里是不正确的。在N4141(C++14)中,我们有:
如果新的表达式创建了一个类类型的对象数组,析构函数可能会被调用(12.4)
(5.3.4/19[expr.new])和
A如果可能被调用的析构函数被删除或无法从上下文中访问,则程序格式错误调用的。
(12.4/11[class.dtor])。因此,应该拒绝这两种数组情况(Clang确实做到了,直播。)
原因是,正如其他人和我以前错误的回答所提到的,类类型元素的构造可能会因异常而失败。当这种情况发生时,必须调用所有完全构造元素的析构函数,因此析构函数必须是可访问的。
当分配具有operator new
(没有[]
)的单个元素时,这种限制不适用,因为如果单个构造函数调用失败,就不可能有完全构造的类实例。
我不是一名语言律师(非常熟悉该标准),但怀疑答案与Baum mit Augen早些时候给出的答案一致(已删除,因此只有那些有足够声誉的人才能看到)。
如果后续数组元素的构造失败并引发异常,则需要删除已构造的元素,从而需要访问析构函数。
但是,如果构造函数是noexcept
,则可以排除这种情况,并且不需要访问析构函数。即使在这种情况下,gcc和clang仍然会抱怨,这很可能是一个编译器错误。也就是说,编译器没有考虑到构造函数是noexcept
。或者,编译器可能在标准中,在这种情况下,这闻起来像是标准中的缺陷。
- 这是使用回溯的 nqueen 问题,但我使用了动态 2d 数组,我的程序编译良好,但不返回任何输出
- 动态更改数组的大小并读取值.(无矢量)
- 检测到堆损坏:在正常块 c++ 动态 2D 数组之后
- 动态维度数组的 C++ 别名指针
- C++ 在析构函数调用之前删除的动态成员数组
- 从类 c++ 动态创建数组
- 具有静态 std::array 的神经网络比使用动态 C 数组的神经网络慢
- "Error reading character of string" 为哈希动态增长数组的问题 (C++)
- 为什么我们在传递动态 2D 数组时不需要列数?
- 如何解决在使用动态 2D 数组进行矩阵乘法的 MPI 进行并行编程时的问题
- 使用动态布尔数组时出现问题
- C++ 在类中删除动态 2D 数组时不断"Aborted (core dumped)"
- 如何在C 中动态输入数组
- 关于删除动态对象数组
- 在C 中动态更改数组大小
- 使用动态指针数组进行动态对象分配 - 使用什么删除?
- 动态字符串数组分配错误
- 函数中的动态 2D 数组分配并将其返回给主数组
- c++动态字符串数组分配
- 使用字符串或字符动态分配(数组)