Clause 15: Let operator = return * This reference

Source: Internet
Author: User

Bjarne stroustrup, the C ++ designer, has made great efforts to make user-defined types work in the same way as fixed types. This is why you can overload operators, write type conversion functions (see article 5), control assignment and copy constructors, and so on. If he has made so much effort, you should at least continue.

Let's take a look at the value assignment. When a fixed type is used, the value assignment operation can be chained like the following:

int w, x, y, z;w = x = y = z = 0;

Therefore, you should also be able to link user-defined value assignment operations:

String w, x, y, z; // string is a type defined by the Standard C ++ library // "Custom" // (see clause 49) W = x = y = z = "hello ";

Because the combination of the assignment operators is inherently from right to left, the assignment above can be parsed:

w = (x = (y = (z = "hello")));

It is worth writing it into a fully equivalent function form. Unless it is a lisp programmer, the following example will be very pleased because it defines an infix OPERATOR:

w.operator=(x.operator=(y.operator=(z.operator=("hello"))));

This format is descriptive here because it emphasizes that the parameters w. Operator =, X. Operator = and Y. Operator = are the return values of the previous operator = call. Therefore, the return value of operator = must be accepted by the function as an input parameter. In Class C, the default operator = function has the following form (see article 45 ):

c& c::operator=(const c&);

In general, operator = always follows the principle that the input and return are referenced by class objects. However, sometimes operator = needs to be overloaded so that it can accept different types of parameters. For example, the standard string type provides two value assignment operators of different versions:

String & // assign a stringoperator = (const string & RHs); // assign a stringstring & // assign a char * operator = (const char * RHs ); // assign a string

Note that, even in the case of overload, the return type is also a reference to the class object.

A common mistake made by C ++ programmers is to let operator = return void. It seems that there is nothing unreasonable, but it hinders the continuous (chained) Assignment operation, so do not do this.

Another common mistake is to let operator = return a reference to a const object, as shown below:

class widget {public:...const widget& operator=(const widget& rhs); ...};

This is usually done to prevent the program from doing stupid operations like the following:

Widget W1, W2, W3 ;... (W1 = W2) = W3; // W2 is assigned to W1, and W3 is assigned to the result. // (the return value for operator = a const is returned. // The statement cannot be compiled)

This may be silly, but it is not stupid to do this for a fixed type:

Int I1, I2, I3;... (I1 = I2) = I3; // valid! I2 is assigned to I1 // then I3 is assigned to I1!

This method is rarely seen in practice, but it can be used for int and for my class. Then it should be fine for you and your class. Why is it necessary to be incompatible with conventional fixed-type practices for no reason?

In the value assignment operator defined by default, the object return value has two obvious candidates: the object on the left of the value assignment statement (the object pointed by this pointer) and the object to the right of the value assignment statement (the object named in the parameter table ). Which one is correct?

For example, for the string class (if you want to write the value assignment operator in this class, see the description in clause 11), there are two possibilities:

String & string: Operator = (const string & RHs ){... return * This; // return the object on the left} string & string: Operator = (const string & RHs ){... return RHS; // return the object on the right}

For you, it seems as difficult as taking the half of six and twelve. In fact, they are quite different.

First, the version that returns RHS will not be compiled because RHS is a const string reference, and operator = returns a string reference. When you want to return a non-const reference and the object itself is const, the compiler will bring you endless pain. It seems that this problem can be easily solved-just re-declare operator = like this:

string& string::operator=(string& rhs){ ... }

This time, the application that uses it cannot be compiled! Let's take a look at the following parts of the original continuous value assignment statement:

X = "hello"; // The same as X. Op = ("hello ");

Because the parameter on the right of the value assignment statement is not of the correct type-it is a character array, not a string-the compiler will produce a temporary String object (through the stirng constructor-see the terms of M19) make the function continue to run. That is to say, the compiler must generate code like the following:

Const string temp ("hello"); // generate temporary stringx = temp; // transmit the temporary string to operator =

The compiler generally generates such a temporary value (unless the required constructor is explicitly defined-See Clause 19), but note that the temporary value is a const. This is important because it can prevent the temporary values passed to the function from being modified. Otherwise, programmers will find it strange that only the temporary values generated by the compiler can be modified, but the parameters actually passed in during function calls cannot. (This is based on facts. In earlier versions, C ++ allowed such temporary values to be generated, transmitted, modified, and many programmers may find it strange)

Now we can know that if the string operator = declares to pass a non-const stirng parameter, the reason why the application cannot pass the compilation: for a function that does not declare the corresponding parameter as const, it is invalid to pass a const object. This is a simple rule about Const.

Therefore, the conclusion is that in this case, you have no choice: when defining your own value assignment operator, you must return the reference of the parameter on the left of the value assignment operator, * This. If you do not do this, you cannot assign values consecutively, or call implicit conversions cannot be performed, or both cases occur simultaneously.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.