
Moving objects
Temporary objects are everywhere in code. Most of the time, they are required to make the code work as expected. For example, when we add two objects together, a temporary object is created to hold the return value of operator+:
Warehouse small;
Warehouse mid;
// ... some data inserted into the small and mid objects
Warehouse large{small + mid}; // operator+(small, mid)
Let's take a look at the implementation of the global operator+() for Warehouse objects:
// considering declared as friend in the Warehouse class
Warehouse operator+(const Warehouse& a, const Warehouse& b) {
Warehouse sum; // temporary
sum.size_ = a.size_ + b.size_;
sum.capacity_ = a.capacity_ + b.capacity_;
sum.products_ = new Product[sum.capacity_];
for (int ix = 0; ix < a.size_; ++ix) { sum.products_[ix] = a.products_[ix]; }
for (int ix = 0; ix < b.size_; ++ix) { sum.products_[a.size_ + ix] = b.products_[ix]; }
return sum;
}
The preceding implementation declares a temporary object and returns it after filling it with necessary data. The call in the previous example could be translated into the following:
Warehouse small;
Warehouse mid;
// ... some data inserted into the small and mid objects
Warehouse tmp{operator+(small, mid)};
Warehouse large;
Warehouse_copy_constructor(large, tmp);
__destroy_temporary(tmp);
The move semantics, which was introduced in C++11, allows us to skip the temporary creation by moving the return value into the Warehouse object. To do so, we should declare a move constructor for the Warehouse, which can distinguish between temporaries and treat them efficiently:
class Warehouse {
public:
Warehouse(); // default constructor
Warehouse(const Warehouse&); // copy constructor
Warehouse(Warehouse&&); // move constructor
// code omitted for brevity
};
The parameter of the move constructor is an rvalue reference (&&).