- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
Comeau、g++ (ideone) 和 EDG 接受以下代码而不进行诊断。 Visual C++ 编译成功,但出现警告 C4624。
class indestructible_base
{
~indestructible_base();
};
class T : indestructible_base
{
public:
//T() {}
};
int main(void) { new T(); }
取消注释构造函数,它不再编译。
也许是这样的规则,如果构造函数内部发生异常,必须销毁子对象?看起来很奇怪,因为主体是空的并且不会导致异常。即便如此,添加一个异常规范来保证不会抛出异常(throw()
或 noexcept
),这没有任何区别。
为什么用户声明的构造函数需要访问基类析构函数,而自动生成的构造函数不需要?
最佳答案
我怀疑这可能是特定于编译器的行为。这是我的理论:
因为(在这种特殊情况下)隐式定义的 T() 是一个 普通 构造函数(在标准的 12.1(5) 中定义),编译器甚至不会尝试生成T() 的主体。由于没有 ctor 主体,因此在“构造”期间不会产生任何异常(实际上没有任何异常),因此无需生成 dtor 调用,因此无需生成 dtor 主体, 才发现基类的 dtor 是私有(private)的。
但是一旦 T() 变得不平凡(即使它仍然是隐式定义的),就必须生成一个 ctor 主体,并且您会收到错误。像向具有用户定义的构造函数的类 T 添加成员这样简单的事情会使隐式定义的 T() 变得不平凡。
一个单独但相关的问题是 new T()
不会生成 dtor 调用(因为您在任何地方都没有相应的 delete
)。相反,如果我只是在您的代码中将 new T()
替换为 T dummy
,那么我会从 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'
关于c++ - 为什么只有在声明自定义构造函数时才能访问基类析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9123214/
我是一名优秀的程序员,十分优秀!