C++的几种特殊函数:拷贝构造函数,拷贝赋值函数,移动构造函数,移动赋值函数,析构函数
目录
1、前言
2、拷贝构造函数
2.1 什么是拷贝构造函数
2.2 拷贝构造函数签名
2.3 拷贝构造函数定义
2.4 拷贝构造函数的使用场景
2.5 拷贝构造函数的注意事项
3、拷贝赋值函数
3.1 什么是拷贝赋值函数
3.2 拷贝赋值函数签名
3.3 拷贝赋值函数定义
3.4 拷贝构造函数的触发时机
4、移动构造函数
4.1 什么是移动构造函数
4.2 移动构造函数签名
4.3 移动构造函数定义
4.4 移动构造函数的使用场景
4.5 为什么移动构造通常要 noexcept?
5、移动赋值函数
5.1 什么是移动赋值函数?
5.2 移动赋值函数签名
5.3 移动赋值函数定义
5.4 移动赋值函数调用场景
5.5 移动构造和移动赋值的区别
6、析构函数
6.1 什么是析构函数
6.2 析构函数签名
6.3 析构函数定义
7、一个包含这些函数的完整示例
8、总结
9、参考链接
非AI生成,觉得有用,就请您帮忙点赞转发收藏吧,您的鼓励是我创作的动力,多谢看官。
由于能力水平有限,文中的错误或不严谨的地方,还请批评指正。
1、前言
这五个函数共同构成 C++ 的对象生命周期管理核心,合称“五法则(Rule of Five)”。它们控制对象拷贝、移动、销毁时的资源行为,尤其对堆内存、文件句柄、锁等资源类至关重要。
2、拷贝构造函数
2.1 什么是拷贝构造函数
C++ 拷贝构造函数是一种特殊的构造函数,用于用一个已存在的同类型对象初始化新对象,其第一个参数必须是本类对象的引用(通常加const),由编译器在特定场景下自动调用 。
2.2 拷贝构造函数签名
ClassName(const ClassName& other)
2.3 拷贝构造函数定义
MyString(const MyString& other) {
m_Size = other.m_Size;
m_Data = new char[m_Size + 1]; // 重新分配内存
std::memcpy(m_Data, other.m_Data, m_Size + 1);
std::cout << "拷贝构造函数被调用" << std::endl;
}
2.4 拷贝构造函数的使用场景
初始化新对象:
A b(a);或A b = a;(声明时)值传递参数:函数参数为类类型对象(按值传入)
值返回对象:函数返回类类型对象(按值返回)
MyClass a;
MyClass b = a; // 拷贝构造
MyClass c(a); // 拷贝构造
func(a); // 传值,拷贝构造
return a; // 返回对象,拷贝构造(可能被NRVO优化掉)
2.5 拷贝构造函数的注意事项
如果没有定义任何拷贝函数,编译器会生成一个默认的拷贝构造函数。
默认拷贝构造函数的行为:
逐成员拷贝(member-wise copy)
对类类型成员:调用它们的拷贝构造函数
对内置类型成员:直接按位复制
当类中管理了资源(尤其是裸指针)时,由于默认拷贝是浅拷贝,会出严重问题,出现双重释放的可能性比较大。
3、拷贝赋值函数
3.1 什么是拷贝赋值函数
C++中的拷贝赋值函数(Copy Assignment Operator)是通过重载operator=实现的非静态成员函数,用于将已存在的同类型对象数据深拷贝给另一个已存在的对象 。
3.2 拷贝赋值函数签名
ClassName& operator=(const ClassName& other)
3.3 拷贝赋值函数定义
MyString& operator=(const MyString& other) {
std::cout << "拷贝赋值运算符被调用" << std::endl;
if(this != &other) { // 1. 检查自赋值
delete[] m_Data; // 2. 释放旧内存m_Size = other.m_Size;
m_Data = new char[m_Size + 1]; // 3. 分配新内存
std::memcpy(m_Data, other.m_Data, m_Size + 1);
}
return *this;
}
