Online Book Reader

Home Category

Professional C__ - Marc Gregoire [139]

By Root 1519 0
rhs)

{

// check for self-assignment

if (this == &rhs) {

return *this;

}

// free the old memory

for (int i = 0; i < mWidth; i++) {

delete [] mCells[i];

}

delete [] mCells;

mCells = nullptr;

// Shallow copy of data

mWidth = rhs.mWidth;

mHeight = rhs.mHeight;

mCells = rhs.mCells;

// Reset the source object

rhs.mWidth = 0;

rhs.mHeight = 0;

rhs.mCells = nullptr;

return *this;

}

Code snippet from SpreadsheetMoveSemantics\Spreadsheet.cpp

Both the move constructor and the move assignment operator are moving ownership of the memory for mCells from the source object to the new object. They reset the mCells pointer of the source object to a null pointer to prevent the destructor of the source object to deallocate that memory, because now the new object is the owner of that memory.

The preceding move constructor and move assignment operator can be tested with the following code:

Spreadsheet CreateObject()

{

return Spreadsheet(3, 2);

}

int main()

{

vector vec;

for (int i = 0; i < 2; ++i) {

cout << "Iteration " << i << endl;

vec.push_back(Spreadsheet(100, 100));

cout << endl;

}

Spreadsheet s(2,3);

s = CreateObject();

Spreadsheet s2(5,6);

s2 = s;

return 0;

}

Code snippet from SpreadsheetMoveSemantics\SpreadsheetTest.cpp

Chapter 1 introduces the vector. A vector grows dynamically in size to accommodate new objects. This is done by allocating a bigger chunk of memory and then copying or moving the objects from the old vector to the new and bigger vector. If the compiler finds a move constructor, the objects will be moved instead of copied. By moving them there is no need for any deep copying making it much more efficient.

When you add output statements to all constructors and assignment operators of the Spreadsheet class, the output of the preceding test program will be as follows:

Iteration 0

Normal constructor (1)

Move constructor (2)

Iteration 1

Normal constructor (3)

Move constructor (4)

Move constructor (5)

Normal constructor (6)

Normal constructor (7)

Move assignment operator (8)

Normal constructor (9)

Assignment operator (10)

On the first iteration of the loop, the vector is still empty. Take the following line of code from the loop:

vec.push_back(Spreadsheet(100, 100));

With this line, a new Spreadsheet object is created which will invoke the normal constructor (1). The vector will resize itself to make space for the new object being pushed in. The created Spreadsheet object is then moved into the vector, invoking the move constructor (2).

On the second iteration of the loop, a second Spreadsheet object is created with the normal constructor (3). At this point, the vector can hold one element, so it’s again resized to make space for a second object. By resizing the vector, the previously added elements need to be moved from the old vector to the new and bigger vector, so this will trigger a call to the move constructor for each previously added element (4). Then, the new Spreadsheet object is moved into the vector with its move constructor (5).

The CreateObject function creates a temporary Spreadsheet object with its normal constructor (7), which is then returned from the function and move-assigned to the variable s (8). Because the temporary object will cease to exist after the assignment, the compiler will invoke the move assignment operator instead of the normal copy assignment operator. On the other hand, the assignment s2 = s will invoke the copy assignment operator (10) because the right-hand side object is not a temporary object, but a named object.

If the Spreadsheet class did not include a move constructor and move assignment operator, the above output would look as follows:

Iteration 0

Normal constructor

Copy constructor

Iteration 1

Normal constructor

Copy constructor

Copy constructor

Normal constructor

Normal constructor

Assignment operator

Normal constructor

Assignment operator

As you can see, copy constructors are called instead of move constructors and copy assignment operators are called instead of move assignment operators.

Return Main Page Previous Page Next Page

®Online Book Reader