官术网_书友最值得收藏!

Rvalue references

We cannot bind lvalue references to temporaries. The following code won't compile:

int get_it() {
int it{42};
return it;
}
...
int& impossible{get_it()}; // compile error

We need to declare an rvalue reference to be able to bind to temporaries (including literal values):

int&& possible{get_it()};

Rvalue references allow us to skip the generation of temporaries as much as possible. For example, a function that takes the result as an rvalue reference runs faster by eliminating temporary objects:

void do_something(int&& val) {
// do something with the val
}
// the return value of the get_it is moved to do_something rather than copied
do_something(get_it());

To imagine the effect of moving, imagine that the preceding code will be translated into the following (just to get the full idea of moving):

int val;
void get_it() {
val = 42;
}
void do_something() {
// do something with the val
}
do_something();

Before moving was introduced, the preceding code would look like this (with some compiler optimization):

int tmp;
void get_it() {
tmp = 42;
}
void do_something(int val) {
// do something with the val
}
do_something(tmp);

The move constructor, along with the move operator, =(), has the effect of copying without actually carrying out a copy operation when the input argument represents an rvalue. That's why we should also implement these new functions in the class: so that we can optimize the code wherever it makes sense. The move constructor can grab the source object instead of copying it, as shown here:

class Warehouse {
public:
// constructors omitted for brevity
Warehouse(Warehouse&& src)
: size_{src.size_},
capacity_{src.capacity_},
products_{src.products_}
{
src.size_ = 0;
src.capacity_ = 0;
src.products_ = nullptr;
}
};

Instead of creating a new array of capacity_ size and then copying each element of the products_ array, we just grabbed the pointer to the array. We know that the src object is an rvalue and that it will soon be destroyed, which means the destructor will be called and the destructor will delete the allocated array. Now, we point to the allocated array from the newly created Warehouse object, which is why we cannot let the destructor delete the source array. Due to this, we assign nullptr to it to make sure the destructor will miss the allocated object. So, the following code will be optimized because of the move constructor:

Warehouse large = small + mid;

The result of + operator will be moved rather than copied. Take a look at the following diagram:

The preceding diagram demonstrates how the temporary is being moved to the large object.

主站蜘蛛池模板: 九龙坡区| 铜梁县| 汾阳市| 霍林郭勒市| 青海省| 田东县| 辽宁省| 电白县| 改则县| 长武县| 临沧市| 芒康县| 错那县| 贵阳市| 海丰县| 秭归县| 萍乡市| 江西省| 赤城县| 昌都县| 沈丘县| 阿拉善盟| 泊头市| 绥江县| 赣榆县| 镇原县| 温州市| 澎湖县| 昌吉市| 寿宁县| 错那县| 平顺县| 咸丰县| 阿图什市| 孟州市| 舟曲县| 平和县| 普宁市| 都兰县| 萨嘎县| 淳化县|