右值引用

右值引用

那么当类中包含指针类型的成员变量,使用其它对象来初始化同类对象时,怎样才能避免深拷贝导致的效率问题呢?C++11 标准引入了解决方案,该标准中引入了右值引用的语法,借助它可以实现移动语义。

C++移动构造函数(移动语义的具体实现)

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
#include <iostream>
using namespace std;
class demo{
public:
demo():num(new int(0)){
cout<<"construct!"<<endl;
}

demo(const demo &d):num(new int(*d.num)){
cout<<"copy construct!"<<endl;
}
//添加移动构造函数
demo(demo &&d):num(d.num){
d.num = NULL;
cout<<"move construct!"<<endl;
}
~demo(){
cout<<"class destruct!"<<endl;
}
private:
int *num;
};
demo get_demo(){
return demo();
}
int main(){
demo a = get_demo();
return 0;
}

情况2

如果一个类拥有一个资源(并使用普通指针管理它),那么拷贝成员就必须拷贝此资源。一般来说,拷贝一个资源会导致一些额外开销。在这种拷贝并非必要的情况下,通过定义移动构造函数和移动赋值运算符就可以避免此问题。

而移动成员的参数就是一个右值引用类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class A {

public:

A() = default;

~A() { if (m_str) delete m_str; }

// 移动构造函数

A(A &&a) noexcept : m_*str(a.m_*str) { a.m_str = nullptr; }

private:

char *m_str = nullptr;

}