问题描述
如果我有一个像这样定义的类
If I have a class defined like
class A {
protected:
~A(){ }
};
然后我可以动态分配单个对象以及对象数组,例如
then I can dynamically allocate the individual as well as array of objects like
A* ptr1 = new A;
A* ptr2 = new A[10];
但是,当我为此类定义构造函数时
However when I define the constructor for this class
class A {
public:
A(){}
protected:
~A(){ }
};
然后我可以使用创建单个对象
then I can create individual objects with
A* ptr = new A;
但是当我尝试动态分配对象数组时
but when I try to dynamically allocate the array of object with
A* ptr = new A[10];
编译器(gcc-5.1和Visual Studio 2015)开始抱怨A ::〜A()无法访问.
compiler(gcc-5.1 and Visual Studio 2015) starts complaining that A::~A() is inaccessible.
谁能解释一下:-
1-为什么定义和未定义构造函数的行为差异.
1- Why is the difference in behavior with constructor being defined and not defined.
2-定义了构造函数后,为什么可以创建单个对象而不是对象数组.
2- When the constructor is defined why I am allowed to create individual object and not array of object.
推荐答案
拒绝带有受保护的析构函数的数组-new
是正确的,按照C ++ 11,第5.3.4节¶17:
Rejecting an array-new
with a protected destructor is correct, as per C++11, §5.3.4 ¶17:
(强调已添加; C ++ 03,第5.3.4节¶16中使用的措词几乎完全相同; C ++ 14提出了一些建议,但似乎并没有改变问题的核心-参见 @Baum mit Augen的答案)
(emphasis added; almost exactly the same wording is used in C++03, §5.3.4 ¶16; C++14 moves some stuff around, but that doesn't seem to change the core of the issue - see @Baum mit Augen's answer)
这是因为,只有在所有元素都已构造后,new[]
才会成功,并且要避免在一个构造函数调用失败的情况下泄漏对象.因此,如果它设法构造(例如)前9个对象,但第10个对象失败并出现异常,则必须在传播该异常之前破坏前9个对象.
That comes from the fact that new[]
succeeds only if only all the elements have been constructed, and wants to avoid leaking objects in case one of the costructor calls fails; thus, if it manages to construct - say - the first 9 objects but the 10th fails with an exception, it has to destruct the first 9 before propagating the exception.
请注意,如果将构造函数声明为noexcept
,则从逻辑上讲不需要此限制,但是标准似乎在这方面没有任何例外.
Notice that this restriction logically wouldn't be required if the constructor was declared as noexcept
, but still the standard doesn't seem to have any exception in this regard.
因此,这里的gcc在第一种情况下在技术上是错误的,就标准而言,它也应被拒绝,尽管我认为道德上"的gcc做对了(实际上, A
的默认构造函数无法抛出).
So, here gcc is technically wrong in the first case, which, as far as the standard is concerned, should be rejected as well, although I'd argue that "morally" gcc does the right thing (as in practice there's no way that the default constructor of A
can ever throw).
这篇关于具有受保护的析构函数的类数组的动态分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!