提问人:TonySalimi 提问时间:6/28/2019 最后编辑:TonySalimi 更新时间:3/20/2020 访问量:2828
何时使用 =default 使析构函数默认?
When to make a destructor defaulted using =default?
问:
尽管对构造函数使用 =default 对我来说很清楚(即强制编译器在其他 ctor 存在时创建默认构造函数),但我仍然无法理解这两种类型的析构函数之间的区别:
- 那些使用 =default
- 那些没有显式定义并由编译器自动生成的那些。
我唯一想到的是,group-1 析构函数可以定义为虚拟的,但 group-2 始终是非虚拟的。那么,这是它们之间的唯一区别吗?是否有任何情况是编译器没有生成析构函数,但使用 =default 强制编译器生成它?
p.s. 我在 stackoverflow 中检查了很多 Q,但没有一个回答我的 Q。以下是一些相关问题。
编辑 1:这个关于 SO 的 Q 侧重于禁用默认移动构造函数,这可以被视为已接受答案中提到的项目之一。
答:
(以下几点已经在评论或链接的问题中提到过;这个答案有助于组织和相互关联。
当然,有三种方法可以得到一个“简单析构函数”:
struct Implicit {};
struct Empty {~Empty() {}};
struct Defaulted {~Defaulted()=default;};
就像默认(而不是复制或移动)构造函数一样,对于析构函数来说,含义大致相同。有趣的属性是那些与其他两个不同的(组合)。{}
=default;
Defaulted
与主要区别很简单:显式默认的析构函数可能微不足道。仅当它在类内默认时才适用,因此在行外定义和 之间没有区别。同样,虚拟消除了任何区别,就像任何成员或基类都具有非平凡的析构函数一样。还有一个区别是,显式默认的析构函数可以隐式定义为已删除。这两个属性都与隐式声明的析构函数共享,因此我们也必须找到与这些属性的区别。Empty
{}
=default;
与 相比,显式默认的析构函数抑制移动操作,可以声明 、 或 noexcept(false),
并且在 C++20 中可以约束(但不能)。非常微不足道,可以声明以验证它无论如何都会。声明它不会做任何事情。(它也可以是不合时宜的或虚拟的,但如上所述,这不能成为使用它的理由。Implicit
private
protected
consteval
constexpr
inline
因此,答案是“当您想要一个具有其他特殊属性的琐碎(或可能被删除)的析构函数时”——最有用的是访问控制或状态。noexcept
下一个:如何绘制重复值的线性图
评论
= default
pimpl
~X();
~X() = default;
pimpl
protected
private