首页 > 解决方案 > 何时使用 =default 使析构函数默认?

问题描述

尽管对我来说使用 =default 构造函数很清楚(即强制编译器在存在其他 ctor 的情况下创建默认构造函数),但我仍然无法理解这两种析构函数之间的区别:

  1. 那些使用 =default
  2. 那些没有明确定义并由编译器自动生成的。

我唯一想到的是 group-1 析构函数可以定义为虚拟的,但 group-2 始终是非虚拟的。那么,这就是他们之间的唯一区别吗?是否存在编译器不生成析构函数,但使用 =default 强制编译器生成它的情况?

ps我在stackoverflow中检查了很多Q,但没有一个回答我的Q。这里有一些相关的问题。

  1. =default 和 {} ctos/destructors 之间的区别
  2. 默认虚拟析构函数
  3. =default 和空 dtrs 之间的区别

编辑 1: 这个关于 SO 的 Q侧重于禁用默认移动构造函数,可以将其视为已接受答案中提到的项目之一。

标签: c++c++11destructor

解决方案


(以下几点已在评论或链接问题中提到;此答案用于组织和相互关联。)

当然有三种方法可以得到一个“简单的析构函数”:

struct Implicit {};
struct Empty {~Empty() {}};
struct Defaulted {~Defaulted()=default;};

就像默认(而不是复制或移动)构造函数一样{}=default;对于析构函数的含义大致相同。有趣的属性Defaulted是那些(组合)与其他两个不同的属性。

Empty主要区别很简单:显式默认的析构函数可以是微不足道的。{}这仅适用于它在类内部被默认的情况,因此=default;外线定义之间没有区别。类似地,虚拟化消除了任何区别,任何成员或基类都具有非平凡的析构函数。还有一个区别是显式默认的析构函数可以隐式定义deleted。这两个属性都与隐式声明的析构函数共享,因此我们也必须找到它们的区别。

VersusImplicit是一个显式默认的析构函数抑制移动操作,可以声明为privateprotectednoexcept(false),并且在 C++20 中可以被约束(但不是consteval)。非常轻微地,可以声明constexpr它以验证它无论如何都会是。声明它inline没有任何作用。(它也可以是脱机的或虚拟的,但如上所述,这不能成为使用它的理由。)

所以答案是“当你想要一个具有其他特殊属性的微不足道的(或可能被删除的)析构函数时”——最有用的是访问控制或noexcept状态。


推荐阅读