如果我有一个像

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,拒绝带有 protected 析构函数的new数组是正确的:



(添加了重点;在C++ 03,§5.3.4¶16中使用几乎完全相同的措辞; C++ 14进行了一些改动,但这似乎并没有改变问题的核心-参见@Baum麻省理工学院的答案)

这是由于new[]仅在所有元素都已构建时才成功,并且希望避免在构造函数调用之一失败的情况下泄漏对象。因此,如果它设法构造(例如)前9个对象,但第10个对象失败并出现异常,则它必须在传播该异常之前破坏前9个对象。

请注意,如果将构造函数声明为noexcept,则从逻辑上讲不需要此限制,但是在这方面标准似乎也没有异常(exception)。

因此,这里的gcc在第一种情况下在技术上是错误的,就标准而言,它也应被拒绝,尽管我认为“道德上”的gcc做对了(因为实际上, A的默认构造函数可以抛出)。

关于c++ - 具有 protected 析构函数的类数组的动态分配,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41779374/

10-11 23:05
查看更多