c++ - 何时使用 =default 使析构函数默认?
问题描述
尽管对我来说使用 =default 构造函数很清楚(即强制编译器在存在其他 ctor 的情况下创建默认构造函数),但我仍然无法理解这两种析构函数之间的区别:
- 那些使用 =default
- 那些没有明确定义并由编译器自动生成的。
我唯一想到的是 group-1 析构函数可以定义为虚拟的,但 group-2 始终是非虚拟的。那么,这就是他们之间的唯一区别吗?是否存在编译器不生成析构函数,但使用 =default 强制编译器生成它的情况?
ps我在stackoverflow中检查了很多Q,但没有一个回答我的Q。这里有一些相关的问题。
编辑 1: 这个关于 SO 的 Q侧重于禁用默认移动构造函数,可以将其视为已接受答案中提到的项目之一。
解决方案
(以下几点已在评论或链接问题中提到;此答案用于组织和相互关联。)
当然有三种方法可以得到一个“简单的析构函数”:
struct Implicit {};
struct Empty {~Empty() {}};
struct Defaulted {~Defaulted()=default;};
就像默认(而不是复制或移动)构造函数一样{}
,=default;
对于析构函数的含义大致相同。有趣的属性Defaulted
是那些(组合)与其他两个不同的属性。
与Empty
主要区别很简单:显式默认的析构函数可以是微不足道的。{}
这仅适用于它在类内部被默认的情况,因此=default;
外线定义之间没有区别。类似地,虚拟化消除了任何区别,任何成员或基类都具有非平凡的析构函数。还有一个区别是显式默认的析构函数可以隐式定义为deleted。这两个属性都与隐式声明的析构函数共享,因此我们也必须找到它们的区别。
VersusImplicit
是一个显式默认的析构函数抑制移动操作,可以声明为private
、protected
或noexcept(false)
,并且在 C++20 中可以被约束(但不是consteval
)。非常轻微地,可以声明constexpr
它以验证它无论如何都会是。声明它inline
没有任何作用。(它也可以是脱机的或虚拟的,但如上所述,这不能成为使用它的理由。)
所以答案是“当你想要一个具有其他特殊属性的微不足道的(或可能被删除的)析构函数时”——最有用的是访问控制或noexcept
状态。
推荐阅读
- html - 如何在图像和文本之间创建一条水平线
- mysql - 如何在不使用 Sequelize 的情况下定义模型?(带有 MySQL 的 Node.JS)
- java - 如何在不点击的情况下在 onCreate 中调用 onclick 函数?
- c++ - C/C++ 中的显式转换
- reactjs - 有没有人成功地将故事书文档与 gatsby 集成在一起?
- maven - swagger-codegen-maven-plugin 最佳实践
- php - 使用 JSON_REMOVE 从 JSON 列中删除整数
- tsql - 从 TSQL 查询中引用 Access 数据库表
- django-rest-framework - 如何在 Django 序列化程序中获取当前对象的 id?
- android - 如何询问用户我的应用会收集一些关于他使用情况的数据?