Online Book Reader

Home Category

Professional C__ - Marc Gregoire [86]

By Root 1136 0
for the assignment to myCell. However, returning anotherCell directly would be inefficient, so you can return a reference to anotherCell.

You could actually declare the assignment operator to return whatever type you wanted, including void. However, you should always return a reference to the object on which it is called because that’s what clients expect.

Defining an Assignment Operator

The implementation of the assignment operator is similar to that of a copy constructor, with several important differences. First, a copy constructor is called only for initialization, so the destination object does not yet have valid values. An assignment operator can overwrite the current values in an object. This consideration doesn’t really come into play until you have dynamically allocated memory in your objects. See Chapter 7 for details.

Second, it’s legal in C++ to assign an object to itself. For example, the following code compiles and runs:

SpreadsheetCell cell(4);

cell = cell; // Self-assignment

Your assignment operator shouldn’t prohibit self-assignment, but also shouldn’t perform a full assignment if it happens. Thus, assignment operators should check for self-assignment at the beginning of the method and return immediately.

Here is the definition of the assignment operator for the SpreadsheetCell class:

SpreadsheetCell& SpreadsheetCell::operator=(const SpreadsheetCell& rhs)

{

if (this == &rhs) {

Code snippet from SpreadsheetCellAssign\SpreadsheetCell.cpp

The previous line checks for self-assignment, but is a bit cryptic. Self-assignment occurs when the left-hand side and the right-hand side of the equals sign are the same. One way to tell if two objects are the same is if they occupy the same memory location — more explicitly, if pointers to them are equal. Recall that this is a pointer to an object accessible from any method called on the object. Thus, this is a pointer to the left-hand side object. Similarly, &rhs is a pointer to the right-hand side object. If these pointers are equal, the assignment must be self-assignment, but because the return type is SpreadsheetCell& we must return a correct value. All assignment operators return *this, and the self-assignment case is no exception:

return *this;

}

this is a pointer to the object on which the method executes, so *this is the object itself. The compiler will return a reference to the object to match the declared return value. Now, if it is not self-assignment, you have to do an assignment to every member:

mValue = rhs.mValue;

mString = rhs.mString;

Here the method copies the values.

return *this;

}

Finally it returns *this, as explained previously.

Explicitly Defaulted and Deleted Assignment Operator

You can explicitly default or delete a compiler generated assignment operator as follows:

SpreadsheetCell& operator=(const SpreadsheetCell& rhs) = default;

or

SpreadsheetCell& operator=(const SpreadsheetCell& rhs) = delete;

Distinguishing Copying from Assignment

It is sometimes difficult to tell when objects are initialized with a copy constructor rather than assigned to with the assignment operator. Essentially, things that look like a declaration are going to be using copy constructors and things that look like assignment statements will be handled by the assignment operator. Consider the following code:

SpreadsheetCell myCell(5);

SpreadsheetCell anotherCell(myCell);

AnotherCell is constructed with the copy constructor.

SpreadsheetCell aThirdCell = myCell;

aThirdCell is also constructed with the copy constructor, because this is a declaration. This line does not call operator=! This syntax is just another way to write: SpreadsheetCell aThirdCell(myCell);. However:

anotherCell = myCell; // Calls operator= for anotherCell.

Here anotherCell has already been constructed, so the compiler calls operator=.

Objects as Return Values

When you return objects from functions or methods, it is sometimes difficult to see exactly what copying and assignment is happening. Recall that the code for getString() looks like this:

string SpreadsheetCell::getString()

Return Main Page Previous Page Next Page

®Online Book Reader