C++11 move()函数:将左值强制转换为右值

Posted RMOS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++11 move()函数:将左值强制转换为右值相关的知识,希望对你有一定的参考价值。

基于 move() 函数特殊的功能,其常用于实现移动语义。

move() 函数的用法也很简单,其语法格式如下:

move( arg )

其中,arg 表示指定的左值对象。该函数会返回 arg 对象的右值形式。

【例 1】move() 函数的基础应用。

#include <iostream>using namespace std;class movedemo{public: movedemo():num(new int(0)){ cout<<"construct!"<<endl; } //拷贝构造函数 movedemo(const movedemo &d):num(new int(*d.num)){ cout<<"copy construct!"<<endl; } //移动构造函数 movedemo(movedemo &&d):num(d.num){ d.num = NULL; cout<<"move construct!"<<endl; }public: //这里应该是 private,使用 public 是为了更方便说明问题 int *num;};int main(){ movedemo demo; cout << "demo2:\n"; movedemo demo2 = demo; //cout << *demo2.num << endl; //可以执行 cout << "demo3:\n"; movedemo demo3 = std::move(demo); //此时 demo.num = NULL,因此下面代码会报运行时错误 //cout << *demo.num << endl; return 0;}

程序执行结果为:

construct!
demo2:
copy construct!
demo3:
move construct!

通过观察程序的输出结果,以及对比 demo2 和 demo3 初始化操作不难得知,demo 对象作为左值,直接用于初始化 demo2 对象,其底层调用的是拷贝构造函数;而通过调用 move() 函数可以得到 demo 对象的右值形式,用其初始化 demo3 对象,编译器会优先调用移动构造函数。

注意,调用拷贝构造函数,并不影响 demo 对象,但如果调用移动构造函数,由于函数内部会重置 demo.num 指针的指向为 NULL,所以程序中第 30 行代码会导致程序运行时发生错误。


【例 2】灵活使用 move() 函数。

#include <iostream>using namespace std;class first {public: first() :num(new int(0)) { cout << "construct!" << endl; } //移动构造函数 first(first &&d) :num(d.num) { d.num = NULL; cout << "first move construct!" << endl; }public: //这里应该是 private,使用 public 是为了更方便说明问题 int *num;};class second {public: second() :fir() {} //用 first 类的移动构造函数初始化 fir second(second && sec) :fir(move(sec.fir)) { cout << "second move construct" << endl; }public: //这里也应该是 private,使用 public 是为了更方便说明问题 first fir;};int main() { second oth; second oth2 = move(oth); //cout << *oth.fir.num << endl; //程序报运行时错误 return 0;}

程序执行结果为:

construct!
first move construct!
second move construct

程序中分别构建了 first 和 second 这 2 个类,其中 second 类中包含一个 first 类对象。如果读者仔细观察不难发现,程序中使用了 2 此 move() 函数:

  • 程序第 31 行:由于 oth 为左值,如果想调用移动构造函数为 oth2 初始化,需先利用 move() 函数生成一个 oth 的右值版本;

  • 程序第 22 行:oth 对象内部还包含一个 first 类对象,对于 oth.fir 来说,其也是一个左值,所以在初始化 oth.fir 时,还需要再调用一次 move() 函数。


以上是关于C++11 move()函数:将左值强制转换为右值的主要内容,如果未能解决你的问题,请参考以下文章

C11性能之道:转移和转发

强制转换为右值

C++ std::move()函数(将一个左值强制转化为右值引用,继而可以通过右值引用使用该值)

C++ std::move()函数(将一个左值强制转化为右值引用,继而可以通过右值引用使用该值)

error C2662 无法将左值绑定到右值 —— 变量永远是左值,即使它的类型为右值引用

右值引用&&