赋值操作符

与类要控制初始化对象的方式一样,类也定义了该类型对象赋值时会发生什么:
Sales_item trans, accum;
trans = accum;

与复制构造函数一样,如果类没有定义自己的赋值操作符,则编译器会合成一个。

重载赋值

重载操作符是一些函数,其名字为 operator 后跟着所定义的操作符的符号。因此,通过定义名为 operator= 的函数,我们可以对赋值进行定义。像任何其他函数一样,操作符函数有一个返回值和一个形参表。形参表必须具有与该操作符数目相同的形参(如果操作符是一个类成员,则包括隐式 this 形参)。赋值是二元运算,所以该操作符函数有两个形参:第一个形参对应着左操作数,第二个形参对应右操作数。

大多数操作符可以定义为成员函数或非成员函数。当操作符为成员函数时,它的第一个操作数隐式绑定到 this 指针。有些操作符(包括赋值操作符)必须是定义自己的类的成员。因为赋值必须是类的成员,所以 this 绑定到指向左操作数的指针。因此,赋值操作符接受单个形参,且该形参是同一类类型的对象。

右操作数一般作为 const 引用传递。赋值操作符的返回类型应该与内置类型赋值运算返回的类型相同。内置类型的赋值运算返回对右操作数的引用,因此,赋值操作符也返回对同一类类型的引用。

例如,Sales_item 的赋值操作符可以声明为:
class Sales_item {
public:
// other members as before
// equivalent to the synthesized assignment operator
Sales_item& operator=(const Sales_item &);
};

合成赋值操作符

合成赋值操作符与合成复制构造函数的操作类似。它会执行逐个成员赋值:右操作数对象的每个成员赋值给左操作数对象的对应成员。除数组之外,每个成员用所属类型的常规方式进行赋值。对于数组,给每个数组元素赋值。
例如,Sales_item 的合成赋值操作符可能如下所示:
// equivalent to the synthesized assignment operator
Sales_item& Sales_item::operator=(const Sales_item &rhs)
{
isbn = rhs.isbn; // calls string::operator=
units_sold = rhs.units_sold; // uses built-in int assignment
revenue = rhs.revenue; // uses built-in double  assignment
return *this;
}
合成赋值操作符根据成员类型使用适合的内置或类定义的赋值操作符,依次给每个成员赋值,该操作符返回 *this,它是对左操作数对象的引用。

复制和赋值常一起使用

可以使用合成复制构造函数的类通常也可以使用合成赋值操作符。我们的Sales_item 类无须定义复制构造函数或赋值操作符,这些操作符的合成版本工作得很好。

然而,类也可以定义自己的赋值操作符。一般而言,如果类需要复制构造函数,它也会需要赋值操作符。
实际上,就将这两个操作符看作一个单元。如果需要其中一个,我们几乎也肯定需要另一个。
相关文章
相关标签/搜索