Move语义是C++11中为了提高性能,减少临时对象的构造和析构而引入的新的语义环境,和Move语义相关的还有右值引用(rvalue reference),这里我们总结一下,Move语义的引入带来了哪些好处,当我们定义一个类时需要注意什么。
####Move语义及移动构造函数####
我们通过代码来看一下Move语义出现的原因及必要性。
假设我们有如下的类定义,TestClass类中含有一个Char*
类型的成员变量,为了实现内存的管理,按照The Big Three
原则,我们需要为这个类定义拷贝构造函数
,析构函数
和赋值操作符
。类的代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class TestClass
{
public:
TestClass(char* _array) : array_pointer(_array){
cout << "Constructor Invoked" << std::endl;
}
~TestClass(){
cout << "Destructor is InVoked" << std::endl;
delete array_pointer;
}
TestClass(const TestClass& rhs){
cout << "Copy Constructor is Invoked" << std::endl;
size_t len = strlen(rhs.array_pointer) + 1;
this->array_pointer = new char[len];
memcpy(this->array_pointer, rhs.array_pointer, len);
}
private:
char* array_pointer;
};
其中拷贝构造函数
的语义为:当我们采用一个对象A去构造新的对象时,拷贝构造函数会被自动调用。拷贝构造函数的参数为const TestClass& rhs
决定了我们无法改变rhs的值。在下列情况下会使用拷贝构造函数:1
2TestClass A(x);
TestClass B(x+y);
对于对象A的构造,拷贝构造函数完全符合我们的期望,因为我们使用了一个 lvalue
来构造A,我们不希望改变x
的内容,以便以后继续保持对x
的引用。但是对于对象B的构造过程,拷贝构造函数明显做了多余的事情:
我们采用
rvalue
即一个临时变量来构造B,在B构造之后,临时变量会被销毁,我们不需要保持对这个临时变量的引用。因此,我们完全可以直接将构造函数中参数rhs
的array_pointer
指针直接给B,这样一来就可以省下B中array_pointer
的初始化以及临时变量中array_pointer
的释放过程。