Team LiB
Previous Section Next Section

13.2. The Assignment Operator

13.2. 赋值操作符

Just as classes control how objects are initialized, they also define what happens when objects of their type are assigned:

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

     Sales_item trans, accum;
     trans = accum;

As with the copy constructor, the compiler synthesizes an assignment operator if the class does not define its own.

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

Introducing Overloaded Assignment

介绍重载赋值

Before we look at the synthesized assignment operator, we need to know a bit about overloaded operators, which we cover in detail in Chapter 14.

在介绍合成赋值操作符之前,需要简单了解一下重载操作符,我们将在第十四章详细介绍。

Overloaded operators are functions that have the name operator followed by the symbol for the operator being defined. Hence, we define assignment by defining a function named operator=. Like any other function, an operator function has a return type and a parameter list. The parameter list must have the same number of parameters (including the implicit this parameter if the operator is a member) as the operator has operands. Assignment is binary, so the operator function has two parameters: The first parameter corresponds to the left-hand operand, and the second to the right-hand operand.

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

Most operators may be defined as member or nonmember functions. When an operator is a member function, its first operand is implicitly bound to the this pointer. Some operators, assignment among them, must be members of the class for which the operator is defined. Because assignment must be a member of its class, this is bound to a pointer to the left-hand operand. The assignment operator, therefore, takes a single parameter that is an object of the same class type. Usually, the right-hand operand is passed as a const reference.

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

The return type from the assignment operator should be the same as the return from assignment for the built-in types (Section 5.4.1, p. 160). Assignment to a built-in type returns a reference to its left-hand operand. Therefore, the assignment operator also returns a reference to the same type as its class.

赋值操作符的返回类型应该与内置类型赋值运算返回的类型相同(第 5.4.1 节)。内置类型的赋值运算返回对右操作数的引用,因此,赋值操作符也返回对同一类类型的引用。

For example, the assignment operator for Sales_item might be declared as

例如,Sales_item 的赋值操作符可以声明为:

     class Sales_item {
     public:
         // other members as before
         // equivalent to the synthesized assignment operator
         Sales_item& operator=(const Sales_item &);
     };

The Synthesized Assignment Operator

合成赋值操作符

The synthesized assignment operator operates similarly to the synthesized copy constructor. It performs memberwise assignment: Each member of the right-hand object is assigned to the corresponding member of the left-hand object. Except for arrays, each member is assigned in the usual way for its type. For arrays, each array element is assigned.

合成赋值操作符与合成复制构造函数的操作类似。它会执行逐个成员赋值:右操作数对象的每个成员赋值给左操作数对象的对应成员。除数组之外,每个成员用所属类型的常规方式进行赋值。对于数组,给每个数组元素赋值。

As an example, the synthesized Sales_item assignment operator would look something like:

例如,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;
     }

The synthesized assignment operator assigns each member in turn, using the built-in or class-defined assignment operator as appropriate to the type of the member. The operator returns *this, which is a reference to the left-hand object.

合成赋值操作符根据成员类型使用适合的内置或类定义的赋值操作符,依次给每个成员赋值,该操作符返回 *this,它是对左操作数对象的引用。

Copy and Assign Usually Go Together

复制和赋值常一起使用

Classes that can use the synthesized copy constructor usually can use the synthesized assignment operator as well. Our Sales_item class has no need to define either the copy constructor or the assignment operator: The synthesized versions of these operators work fine.

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

However, a class may define its own assignment operator. In general, if a class needs a copy constructor, it will also need an assignment operator.

然而,类也可以定义自己的赋值操作符。一般而言,如果类需要复制构造函数,它也会需要赋值操作符。

In fact, these operations should be thought of as a unit. If we require one, we almost surely require the other.

实际上,就将这两个操作符看作一个单元。如果需要其中一个,我们几乎也肯定需要另一个。



We'll see examples of classes that need to define their own assignment operators in Section 13.4 (p. 486) and Section 13.5 (p. 492).

我们将在第 13.4 节第 13.5 节介绍类需要自定义赋值操作符的例子。

Exercises Section 13.2

Exercise 13.7:

When does a class need to define an assignment operator?

类何时需要定义赋值操作符?

Exercise 13.8:

For each type listed in the first exercise in Section 13.1.2 (p. 481) indicate whether the class would need an assignment operator.

对于第 13.1.2 节习题 13.5 中列出的每个类型,指出类是否需要赋值操作符。

Exercise 13.9:

The first exercise in Section 13.1.2 (p. 481) included a skeletal definition for class NoName. Determine whether that class needs an assignment operator. If so, implement it.

第 13.1.2 节习题 13.5 中包括 NoName 类的简单定义。确定这个类是否需要赋值操作符。如果需要,实现它。

Exercise 13.10:

Define an Employee class that contains the employee's name and a unique employee identifier. Give the class a default constructor and a constructor that takes a string representing the employee's name. If the class needs a copy constructor or assignment operator, implement those functions as well.

定义一个 Employee 类,包含雇员名字和一个唯一的雇员标识。为该类定义默认构造函数和参数为表示雇员名字的 string 的构造函数。如果该类需要复制构造函数或赋值操作符,实现这些函数。


Team LiB
Previous Section Next Section