在C++中,编译器会根据类的定义情况自动决定是否生成默认的特殊成员函数(如构造函数、拷贝/移动操作、析构函数)。
1. 用户显式声明相关成员函数
1
2
3
4
5
6
| class Example {
public:
Example() = default; // 允许生成默认构造函数
Example(const Example&) {} // 用户定义的拷贝构造函数
// 编译器不再生成默认的移动构造函数和移动赋值运算符
};
|
2. 用户定义析构函数、拷贝/移动操作的影响
1
2
3
4
5
| class Example {
public:
~Example() {} // 用户定义的析构函数
// 移动操作被隐式删除,拷贝操作可能生成(若无其他限制)
};
|
1
2
3
4
5
| class Example {
public:
Example(const Example&) {} // 用户定义的拷贝构造函数
// 移动操作被隐式删除
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| #include <utility>
#include <string>
#include <iostream>
struct Example {
std::string str;
Example() = default;
Example(const std::string& s): str(s) {
std::cout << "Example()\n";
}
Example(Example&& other) {
str = std::move(other.str);
std::cout << "Example(Example&&)\n";
}
Example& operator=(Example&& other) {
str = std::move(other.str);
std::cout << "operator=(Example&&)\n";
return *this;
}
};
int main() {
Example x1("Hello");
Example x2 = std::move(x1);
Example x3;
x3 = std::move(x2);
}
|
执行结果为:
1
2
3
| Example()
Example(Example&&)
operator=(Example&&)
|
3. 类成员或基类的限制
1
2
3
4
| class Example {
std::unique_ptr<int> ptr; // 不可拷贝
};
// 默认的拷贝构造函数和拷贝赋值运算符被删除
|
1
2
3
4
5
6
7
8
| class NonCopyable {
public:
NonCopyable(const NonCopyable&) = delete;
};
class Derived : public NonCopyable {
// 拷贝构造函数被隐式删除,因为基类的拷贝构造函数被删除
};
|