包括:拷贝构造函数、重载赋值操作符
拷贝构造函数
C++ 支持两种初始化形式:直接初始化、拷贝初始化
A x(100); // 直接初始化,调用构造函数
A y = x; // 拷贝初始化,调用拷贝构造函数
A z(x); // 拷贝初始化,调用拷贝构造函数
以下三种情况会调用拷贝构造函数:
- 对象以值传递的方式传入函数体
- 对象以值传递的方式从函数返回
- 对象需要通过另外一个对象进行初始化
实现形式
1)如果没有显式声明,编译器会自动生成一个默认的拷贝构造函数
默认拷贝构造函数只是实现浅拷贝,对于动态成员只会重新赋值。如对于指针,不会分配新空间。
2)显式声明
// 4种拷贝构造函数形式
A(A&);
A(const A& m_a);
A(volatile A&);
A(const volatile A&);
// 参数列表后如果有其他参数,并且都有默认值也算
A(A&, int a=1);
3)一个技巧
如果想要禁止对象的值传递,可以声明一个私有拷贝构造函数
赋值运算符重载函数
A m_a; // 调用构造函数
A m_b = m_a; // 调用拷贝构造函数
A m_c;
m_c = m_a; // 调用赋值运算符重载函数
实现形式
A& operator =(const A& m_a){
if(this != &m_a){
// to do
}
return *this
}
- 输入是类对象的引用(引用可以避免拷贝提高效率),前面用 const 修饰(避免被修改)
- 输出是被赋值者的引用
- 函数体一般先通过判断 this != &m_a 以避免自赋值
默认赋值运算符重载函数
当程序没有显式提供一个以本类或本类的引用为参数的复制运算符重载函数时,编译器会自动生成一个
- 显式提供重载函数的一个重要场景是需要深拷贝时
- 输入参数必须为本类才算
// 输入为 int ,编译器仍会提供一个默认重载函数
A& operator =(const int data){}
其他
- 赋值运算符重载函数不能被继承
- 赋值运算符重载函数只能是类的非静态成员函数