第十三章 拷贝控制
拷贝构造函数
如果一个构造函数的第一个参数是自身类类型的引用,且任何额外参数都有默认值,则此构造函数是拷贝构造函数
class Foo{
public:
Foo(); // 默认构造函数
Foo(const Foo&); // 拷贝构造函数
// ...
};
作为一个例子,Sales_data
类的合成拷贝构造函数等价于:
class Sales_data{
public:
// 其他成员和构造函数的定义,如前
// 与合成的拷贝构造函数等价的拷贝构造函数的声明
Sales_data(const Sales_data&);
private:
std::string bookNo;
int units_sold = 0;
double revenue = 0.0;
};
// 与 Sales_data 的合成的拷贝构造函数等价
Sales_data::Sales_data(const Sales_data& orig):
bookNo(orig.bookNo), units_sold(orig.units_sold),revenue(orig.revenue)
{}
拷贝初始化不仅在我们用 =
定义变量时会发生,在下列情况下也会发生
- 将一个对象作为实参传递给一个非引用类型的形参
- 从一个返回类型为非引用类型的函数返回一个对象
- 用花括号列表初始化一个数组中的元素或一个聚合类中的成员
拷贝赋值运算符
重载赋值运算符
重载运算符本质上是函数,其名字由 operator
关键字后接表示要定义的运算符的符号组成。因此,赋值运算符就是一个名为 operator=
的函数。
重载运算符的参数表示运算符的运算对象。某些运算符,包括赋值运算符,必须定义为成员函数。如果一个运算符是一个成员函数,其左侧运算对象就绑定到隐式的 this
参数。对于一个二元运算符,例如赋值运算符,其右侧运算对象作为显示参数传递
拷贝赋值运算符接受一个与其所在类相同类型的参数:
class Foo{
public:
Foo& operator=(const Foo&); // 赋值运算符
// ...
};
下面的代码等价于 Sales_data
的合成拷贝赋值运算符
Sales_data&
Sales_data::operator=(const Sales_data& rhs){
bookNo = rhs.bookNo;
units_sold = rhs.units_sold;
revenue = rhs.revenue;
return *this;
}