当前位置:网站首页>本周小贴士131:特殊成员函数和`= default`
本周小贴士131:特殊成员函数和`= default`
2022-07-07 15:39:00 【-飞鹤-】
作为totw#131最初发表于2017年3月24日
由James Dennett ([email protected])创作
从一开始,C++ 就支持一些所谓的特殊成员函数的编译器声明版本:默认构造函数、析构函数、复制构造函数和复制赋值运算符。 C++11 向列表添加了移动构造和移动赋值,并添加了语法(=default 和 =delete)以控制何时声明和定义这些默认值。
=default 有什么作用,我们为什么要使用它?
写 =default 是我们告诉编译器“你通常会为这个特殊成员函数做的事情”的方式。 为什么我们要这样做而不是手动编写实现或让编译器为我们声明一个?
- 我们可以更改访问级别(例如,使构造函数受保护而不是公共),使析构函数为虚拟,或恢复将被抑制的函数(例如,具有其他用户声明的构造函数的类的默认构造函数)并且仍然 让编译器为我们生成函数。
- 如果复制/移动成员就足够了,编译器定义的复制和移动操作不需要在每次添加或删除成员时进行维护。
- 编译器提供的特殊成员函数可以是不重要的(当它们调用的所有对自身的操作是不重要的),这可以使它们更快、更安全。
- 具有默认构造函数的类型可以是聚合的,因此支持聚合初始化,而具有用户提供的构造函数的类型则不能。
- 显式声明一个默认成员为我们提供了一个地方,用来记录结果函数语义。
- 在类模板中,=default 是一种简单方法,去有条件地声明操作,具体取决于某些基础类型是否提供它。
当我们在特殊成员函数的初始声明中使用 =default 时,编译器将检查它是否可以为该函数合成为内联定义。 如果可以,它就进行。 如果不能,该函数实际上被声明为已删除,就像我们写了 =delete 一样。 这正是我们透明地包装类所需要的(例如,如果我们正在定义一个类模板),但读者可能会感到惊讶。
如果函数的初始声明使用 =default,或者如果编译器声明了一个非用户声明的特殊成员函数,则会推导出适当的 noexcept 规范,从而可能允许更快的代码。
它是如何工作的呢?
在C++11之前,如果我们需要一个默认的构造函数或已经有了其他的构造函数,那么我们可以这样写:
class A {
public:
A() {
} // User-provided, non-trivial constructor makes A a non-aggregate.
};
从C++11开始我们有更多选择:
class C {
public:
C() = default; // misleading: C has a deleted default constructor
private:
const int i; // const => must always be initialized.
};
class D {
public:
D() = default; // unsurprising, but not explicit: D has a default constructor
private:
std::unique_ptr<int> p; // std::unique_ptr has a default constructor
};
显然,我们不应该编写类 C 之类的代码:在非模板中,仅当您希望该类支持该操作(然后测试它是否支持)时才使用 =default。 clang-tidy 包括对此的检查。
当在特殊成员函数的第一次声明之后(即在类之外)使用 =default 时,它具有更简单的含义:它告诉编译器定义函数,并在无法这样做时给出错误.当在类外使用 =default 时,默认函数将不是微不足道的:微不足道由第一个声明确定(因此所有客户端都同意操作是否微不足道)。
如果你不需要你的类是一个聚合并且你不需要构造函数是微不足道的,那么在类定义之外默认构造函数,比如下面的示例 E 和 F,通常是一个不错的选择。它的含义对读者来说是清楚的,并由编译器检查。对于默认构造函数或析构函数的特殊情况,我们可以写 {} 而不是 =default,但对于其他默认操作,编译器生成的实现不那么简单,为了保持一致性,最好在所有适用情况下写 =default。
class E {
public:
E(); // promises to have a default constructor, but...
private:
const int i; // const => must always be initialized.
};
inline E::E() = default; // compilation error here: would not initialize `i`
class F {
public:
F(); // promises to have a default constructor
private:
std::unique_ptr<int> p; // std::unique_ptr has a default constructor
};
inline F::F() = default; // works as expected
建议
优先 =default 而不是手动编写等效的实现,即使该实现只是 {}。 可选地,从初始声明中省略 =default 并提供单独的默认实现。
注意默认的移动操作。 来自移动的对象仍然必须满足其类型的不变量,并且默认实现通常不会保留字段之间的关系。
在模板之外,如果 =default 不提供实现,则改为使用 =delete。
边栏推荐
- Sator a lancé le jeu web 3 "satorspace" et a lancé huobi
- 【网络攻防原理与技术】第1章:绪论
- SIGGRAPH 2022最佳技术论文奖重磅出炉!北大陈宝权团队获荣誉提名
- From Devops to mlops: how do it tools evolve to AI tools?
- Skimage learning (3) -- adapt the gray filter to RGB images, separate colors by immunohistochemical staining, and filter the maximum value of the region
- SlashData开发者工具榜首等你而定!!!
- Skimage learning (2) -- RGB to grayscale, RGB to HSV, histogram matching
- [fan Tan] after the arrival of Web3.0, where should testers go? (ten predictions and suggestions)
- Sator推出Web3游戏“Satorspace” ,并上线Huobi
- 99%的人都不知道|私有化部署还永久免费的即时通讯软件!
猜你喜欢
策略模式 - Unity
Mrs offline data analysis: process OBS data through Flink job
Sator launched Web3 game "satorspace" and launched hoobi
SlashData开发者工具榜首等你而定!!!
Reflections on "product managers must read: five classic innovative thinking models"
【可信计算】第十三次课:TPM扩展授权与密钥管理
[Seaborn] combination chart: facetgrid, jointgrid, pairgrid
网络攻防复习篇
【网络攻防原理与技术】第5章:拒绝服务攻击
Skimage learning (3) -- gamma and log contrast adjustment, histogram equalization, coloring gray images
随机推荐
【可信计算】第十三次课:TPM扩展授权与密钥管理
Notes on installing MySQL in centos7
数值 - number(Lua)
【网络攻防原理与技术】第5章:拒绝服务攻击
MySQL implements the query of merging two fields into one field
LeetCode 1043. Separate the array to get the maximum and daily questions
QT picture background color pixel processing method
【TPM2.0原理及应用指南】 12、13、14章
Matplotlib绘图界面设置
浅谈 Apache Doris FE 处理查询 SQL 源码解析
Skimage learning (3) -- adapt the gray filter to RGB images, separate colors by immunohistochemical staining, and filter the maximum value of the region
LeetCode 1654. The minimum number of jumps to get home one question per day
网络攻防复习篇
命令模式 - Unity
How to implement safety practice in software development stage
99%的人都不知道|私有化部署还永久免费的即时通讯软件!
【视频/音频数据处理】上海道宁为您带来Elecard下载、试用、教程
防火墙系统崩溃、文件丢失的修复方法,材料成本0元
LeetCode 1981. Minimize the difference between the target value and the selected element one question per day
Smart logistics platform: make overseas warehouses smarter