9.Special member
一、C++特殊成员函数简介
- C++自动为类生成的特殊成员函数包括:
- 默认构造函数:无参数创建对象。
- 拷贝构造函数:以另一个现有对象为模板创建新对象。
- 拷贝赋值操作符:用另一个现有对象替换现有对象的内容。
- 析构函数:对象离开作用域时被销毁。
1.1 函数调用示例
在以下示例中,每行代码调用的特殊成员函数是:
1 |
|
1.2 拷贝构造函数
拷贝构造函数负责创建对象的深拷贝,必要时进行深度复制。
1 |
|
1.3 拷贝赋值操作符
拷贝赋值操作符需释放对象当前资源后,执行拷贝。注意自赋值情况。
1 |
|
1.4 删除操作
通过显式删除特殊成员函数,可以阻止对象被拷贝。
1 |
|
1.5 三法则与零法则
- 三法则:如果你需要自定义析构函数、拷贝构造函数或拷贝赋值操作符中的任何一个,你可能需要定义所有三个,因为这意味着你的类有资源管理需求。
- 零法则:如果默认操作符满足需求,最好不要自定义这些特殊成员函数。
二、拷贝问题与优化
在C++中,频繁的对象拷贝可能导致性能问题。考虑以下代码片段,它演示了在一个简单场景中对象如何被创建和拷贝:
1 |
|
在没有编译器优化的情况下,这段代码会导致多次StringVector对象的创建和拷贝:
main
函数中声明的words
对象通过默认构造函数创建。findAllWords
函数中的words
对象通过默认构造函数创建。findAllWords
返回时,通过拷贝构造函数创建一个临时对象。- 将临时对象赋值给
main
中的words
对象,调用拷贝赋值操作符。
为了减少不必要的对象拷贝,C++提供了几种优化机制:
2.1 拷贝省略与返回值优化(RVO)
编译器可以优化掉一些不必要的拷贝,特别是函数返回时的临时对象。这种优化称为返回值优化(RVO),直接在调用方的空间创建返回对象,避免额外的拷贝。现代C++编译器智能地应用RVO,减少性能损耗。
2.2 移动语义
C++11引入的移动语义允许对象的资源“转移”而非传统意义上的拷贝。通过使用移动构造函数和移动赋值操作符,可以有效地将一个对象的状态或资源转移到另一个对象,从而避免深度拷贝带来的开销。
例如:
1 |
|
如果findAllWords
返回的对象利用移动语义,那么这里将不会发生深度拷贝,而是资源的转移。
更详细的移动语义后续讲解。
9.Special member
https://ci-tz.github.io/2024/02/12/9-Special-member/