据我理解的标准,一个平凡的析构函数是隐式声明的,其类只有基和非静态成员和平凡的析构函数。鉴于此定义的递归性,在我看来,唯一的“递归停止”条件是找到具有非隐式声明的析构函数(即用户声明)的基本或非静态成员。如果这是正确的,那应该意味着微不足道的析构函数是“不需要做任何事情”的析构函数,因此它将被声明(隐式)但未定义。以另一种方式说:根据标准定义,隐式定义的析构函数(即“它做某事”)不能是微不足道的说法是否正确?
对于那种愚蠢的问题,我很抱歉,但我想澄清一下我脑海中的一些事情......
据我理解的标准,一个平凡的析构函数是隐式声明的,其类只有基和非静态成员和平凡的析构函数。鉴于此定义的递归性,在我看来,唯一的“递归停止”条件是找到具有非隐式声明的析构函数(即用户声明)的基本或非静态成员。如果这是正确的,那应该意味着微不足道的析构函数是“不需要做任何事情”的析构函数,因此它将被声明(隐式)但未定义。以另一种方式说:根据标准定义,隐式定义的析构函数(即“它做某事”)不能是微不足道的说法是否正确?
对于那种愚蠢的问题,我很抱歉,但我想澄清一下我脑海中的一些事情......
不。一个隐式定义的,平凡的析构函数是微不足道的 :) 声明和定义之间的区别是,为了让编译器甚至可以看到析构函数可用,必须始终有一个声明。因此,如果您不提供一个,它将隐式提供一个。
但是现在,如果需要(如果该类类型的对象被销毁),它也会定义一个。无论如何,它必须做一些事情:它需要调用其所有成员和基类的析构函数。一个简单的例子说明了隐式定义析构函数的效果:
struct a {
private:
~a();
};
struct bug {
// note: can't be destructed
a a_;
};
一旦你试图创建一个 bug 的本地对象,编译器就会发出一个错误信号,因为它产生了一个 bug 的析构函数的定义,它试图调用 a 的不可访问的析构函数。
现在,我认为析构函数/构造函数的琐碎性主要用于对您的程序施加约束。例如,具有非平凡版本的对象不能放在联合中。另一方面,您可以删除具有不完整类型的对象,前提是它具有微不足道的析构函数。请注意,如果您的程序无法确定是否实际定义了普通析构函数,则允许编译器省略定义它。这就是所谓的as-if
规则。编译器必须表现得好像它符合标准 - 只要不改变程序的含义,优化就无关紧要。
你的措辞有点不幸。例如,当您用完成员和基类时,当然递归也会结束。这些措辞问题似乎也让你更加困惑。
无论如何,所有隐式声明的析构函数,无论它们是否微不足道,当且仅当它们被使用时才被定义。使用在这里是一个特定的术语。每当 T 对象的生命周期结束时,都会使用T 类型的析构函数。
存在微不足道的析构函数是因为 C 程序员将结构放在联合中。这段代码在 C++ 中应该是合法的,因此为 C++ 发明了普通析构函数的概念。当编译为 C++ 时,所有 C 结构都有微不足道的析构函数。
考虑这两个类:
class A {
};
class B {
private:
A obj;
};
这两个类的析构函数都是隐式定义的。然而,与此同时,按照标准定义,它们都是微不足道的。