C++中的非平凡析构函数是什么?

18

我正在阅读这个链接,它提到了析构函数的 trivial 和 non-trivial。

如果一个类有显式定义的析构函数,或者它拥有具有 non-trivial 析构函数的成员对象或基类,则该类具有 non-trivial 析构函数。

例如,我有一个类:

class C {
    public:
     ~C(); // not explicitly declared.
};

如果C::~C()被隐式定义了,它是否会成为一个平凡的析构函数?

3个回答

29

你把词用混了。你的例子确实声明了一个显式析构函数。但是,你忘记了定义它,所以会得到链接错误。

规则非常简单:你的类有明确的析构函数吗?如果是,则是非平凡的。如果没有,请检查每个非静态成员对象;如果其中任何一个是非平凡的,则你也是非平凡的。


9
顺便说一下:C::~C() { } 仍然是一个非平凡的析构函数。即使你什么都不做,也在做无事。编译器总是会为你创建平凡的析构函数/构造函数。 - Cort Ammon
9
更准确地说,它需要是“隐式定义的”。如果在第一次声明时也“默认声明”,那么用户声明也是可以的。 - Kerrek SB
有趣,我得查一下。我知道=delete,但不知道=default。 - Cort Ammon
@KerrekSB 检查每个非静态成员对象;如果它们中的任何一个是非平凡的 我不明白这是什么意思,什么是非平凡的非静态成员? - Abhishek Mane
@KerrekSB 1. 什么是非静态非平凡对象的意思?2. 你能否举出析构函数会成为“平凡”类型的情况? - Abhishek Mane

4

所以你的意思是,C 的整个声明就是这样:

class C { };

那么,是的:由于C没有成员对象和基类,因此它没有具有非平凡析构函数的成员对象和没有具有非平凡析构函数的基类,因此其隐式定义的析构函数是平凡的。


0

我认为一般来说,它指的是一个实际执行某些操作的析构函数,例如:

  • 释放内存
  • 关闭与数据库的连接
  • 或处理需要释放的任何资源

在这种情况下,析构函数什么也不做。根据描述,从技术上讲,它可能是“非平凡的”,因为它定义了一个构造函数,但无论如何都没有关系,因为它什么也不做。


2
这更像是一个可能会执行某些操作的析构函数。如果析构函数在使用该类的代码(C.cppmain.cpp或其他文件)中定义于不同的翻译单元中,那么当编译器编译main.cpp时,它必须假定需要在自动存储的C实例超出范围时调用C的析构函数,因为它无法知道该析构函数实际上并没有执行任何操作。 - ruakh
1
在这种情况下,析构函数什么也不做。你怎么知道的?析构函数的定义没有给出。 - curiousguy
1
“trivial destructor”是标准中使用的技术术语,而OP的析构函数根据该术语的定义是非平凡的。 - M.M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接