Comeau、g++ (ideone)和EDG接受以下不带诊断的代码。尽管出现了警告C4624,Visual C++仍可成功编译。
class indestructible_base
{
~indestructible_base();
};
class T : indestructible_base
{
public:
//T() {}
};
int main(void) { new T(); }
取消对构造函数的注释,它将不再编译。
也许这是一个规则,如果构造函数中发生异常,子对象必须被销毁?看起来很奇怪,因为主体是空的,不能引起异常。即使如此,添加一个异常规范来证明不会抛出任何异常(throw()
或noexcept
),这并没有什么不同。
为什么用户声明的构造函数需要访问基类析构函数,而自动生成的构造函数则不需要?
发布于 2012-02-04 03:03:20
我怀疑这可能是特定于编译器的行为。这是我的理论:
因为(在本例中)隐式定义的T()是一个微不足道的构造函数(如标准的12.1(5)中所定义的),编译器甚至不会尝试为T()生成主体。因为没有ctor body,所以没有可能在“构造”期间生成的异常(实际上没有任何异常),所以不需要生成dtor调用,也不需要生成dtor body,只需要发现基类的dtor是私有的。
但是,一旦T()变得非常重要(即使它仍然是隐式定义的),就必须生成一个ctor主体,然后您就会得到错误。像向具有用户定义构造函数的类T添加一个成员这样简单的事情就会使隐式定义的T()变得非常重要。
另一个相关的问题是,new T()
不会生成dtor调用(因为您在任何地方都没有相应的delete
)。相反,如果我只是在代码中用T dummy
替换new T()
,那么我会从gcc
得到以下结果,这表明它现在正在对dtor可访问性进行完整的检查(由于必须生成dtor调用):
test.cpp: In destructor 'T::~T()':
test.cpp:3: error: 'indestructible_base::~indestructible_base()' is private
test.cpp:7: error: within this context
test.cpp: In function 'int main()':
test.cpp:12: note: synthesized method 'T::~T()' first required here
test.cpp:12: warning: unused variable 'dummy'
发布于 2012-02-04 01:11:22
好吧,如果自动生成的构造函数调用一个可能抛出的构造函数,那么it will give the same access error。
#include <string>
class indestructible_base
{
~indestructible_base();
std::string s; // <------ this may throw
};
class T : indestructible_base
{
public:
//T() {}
};
int main(void) { new T(); }
所以我猜exceptions就是答案。在ANSI ISO IEC 14882中,唯一的noexcept(true)
字符串构造函数是move构造函数。我认为this应该编译,但有一个人说不可以。
https://stackoverflow.com/questions/9123214
复制相似问题