移动构造函数的调用时机是:用同类的右值对象初始化新对象。当用当前类的左值对象(有名称,能获取其存储地址的实例对象)初始化同类对象时,需要用到 move() 函数,

move 本意为 “移动”,但该函数并不能移动任何数据,它的功能很简单,就是将某个左值强制转化为右值。

1
move( arg )

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#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;

movedemo demo2 = demo; // 因为demo是左值,调用拷贝构造函数(不影响旧对象)

movedemo demo3 = std::move(demo); // move()得到右值,优先调用移动构造函数
// cout << *demo.num << endl; // 错误,此时 demo.num = NULL

return 0;
}

示例:组合类 move 灵活嵌套

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#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:
int *num;
};

class second
{
public:
second() : fir() {}

//用 first 类的移动构造函数初始化 fir
second(second &&sec) : fir(move(sec.fir))
{
cout << "second move construct" << endl;
}

public:
first fir;
};

int main()
{
second oth;
second oth2 = move(oth); // move里面会再调用 move(oth.fir)
//cout << *oth.fir.num << endl; //程序报运行时错误
return 0;
}

转自:http://c.biancheng.net/view/7863.html