析构函数:琐碎与隐含的定义

时间:2009-01-14 12:32:32

标签: c++ destructor

正如我理解标准一样,一个简单的析构函数是一个隐式声明的析构函数,它的类只有基本和非静态成员和简单的析构函数。 鉴于此定义的递归性,在我看来,唯一的“递归停止”条件是找到具有非隐式声明的析构函数的基本或非静态成员(即用户声明)。 如果这是正确的,那应该意味着一个简单的析构函数是“不必做任何事情”,因此它将被声明(隐式)但没有定义。 用另一种方式说:根据标准定义,隐含的定义的析构函数(即“它做某事”)是不是很简单?

对于那种愚蠢的问题感到抱歉,但我想在脑海中澄清一些事情......

3 个答案:

答案 0 :(得分:6)

没有。根据定义,隐式定义的,平凡的析构函数是微不足道的:) declare和define thingy之间的区别在于,为了使编译器甚至看到析构函数可用,必须始终有一个声明。因此,如果您不提供一个,它将隐式提供一个。

但是现在,它还将定义一个,如果需要的话(如果该类类型的对象被销毁)。无论如何,它必须做一些事情:它需要调用其所有成员和基类的析构函数。一个简单的例子,说明了隐式定义析构函数的效果:

struct a {
private:
    ~a();
};

struct bug {
    // note: can't be destructed
    a a_;
};

一旦你尝试创建一个bug的本地对象,编译器就会发出一个错误信号,因为它产生了一个bug的析构函数定义,它试图调用一个无法访问的析构函数。

现在,我认为破坏者/构造函数的琐碎主要用于对程序施加约束。例如,具有非平凡版本的对象不能放入联合中。另一方面,您可以删除具有不完整类型的对象,前提是它具有普通的析构函数。请注意,如果您的程序无法确定是否实际定义了一个简单的析构函数,则允许编译器省略它的定义。这就是所谓的as-if规则。编译器必须表现为 - 如果它符合标准 - 只要它们不改变程序的含义,优化就无关紧要了。

答案 1 :(得分:3)

你的措辞有点不幸。例如。当你用完成员和基类时,递归当然也会结束。那些措辞问题似乎也让你更加困惑。

无论如何,当且仅当它们被使用时,所有隐式声明的析构函数,无论它们是否是微不足道的,都被定义。 已使用是此处的特定术语。只要T对象的生命周期结束,就会使用 类型的析构函数。

存在琐碎的析构函数,因为C程序员将结构放入工会中。这段代码在C ++中应该是合法的,因此为C ++发明了一个简单的析构函数的概念。当编译为C ++时,所有C结构都有简单的析构函数。

答案 2 :(得分:0)

考虑这两个类:

class A {
};

class B {
private:
     A obj;
};

隐式定义了这两个类的析构函数。然而,与此同时,标准定义中的两者都是微不足道的。