C++11的move语义

        移动语义是通过右值引用来匹配临时值,现在C++11提供了std::move方法来讲左值转换为右值,从而方便应用移动语义。

        move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存拷贝。

        move实际上并不能移动任何东西,它唯一的功能是将一个左值强制转换为一个右值引用,使我们可以通过右值引用使用该值,以用于移动语义。强制转换为右值的目的是为了方便实现移动构造。

        这种move语义是很有用的,比如一个对象中有一些指针资源或者动态数组,在对象的赋值或拷贝时就不需要拷贝这些资源了。在C++11之前拷贝构造函数和赋值函数可能要像下面这样定义。假设一个A对象内部有一个资源m_ptr:
 

A& A::operator=(const A& rhs)        
{
    ///销毁m_ptr指向的资源
    ///复制rhs.m_ptr所指的资源,并使用m_ptr指向它
}

        同样A的拷贝构造函数也是这样的。假设这样来使用A:

A foo();    ///foo是一个返回值为类A的函数
A a;
a = foo();

        最后一行将会发生如下操作:

        1、销毁a所持有的资源;

        2、复制foo返回的临时对象所拥有的资源;

        3、销毁临时对象,释放其资源。

        上面的过程是可行的,但是更有效率的办法是直接交互a和临时对象中的资源指针,然后让临时对象的析构函数去销毁a原来拥有的资源。换句话说,当赋值操作符的右边是右值的时候,我们希望赋值操作符被定义成下面这样:

A& A::operator=(const A&& rhs)
{
    ///转移资源的控制权,无须复制
}

        仅仅转移资源的所有权,将资源的拥有者改为被赋值者,这就是所谓的move语义。

        如果不用std::move,拷贝的代价很大,性能较低。使用move几乎没有任何代价,只是转换了资源的所有权。实际上是将左值变成右值引用,然后应用move语义调用构造函数,就避免了拷贝,提高了程序性能。当一个对象内部有较大的堆内存或者动态数组时,很有必要写move语义的拷贝构造函数和赋值函数,避免无谓的深拷贝,以提高性能。事实上,C++中所有的容器都实现了move语义,方便我们实现性能优化。

        如果是一些基本类型,比如int和char[0]数组等,如果使用move,仍然会发生拷贝(因为没有对应的移动构造函数),所以说move对于含有资源的对象来说更有意义。

你可能感兴趣的:(深入应用C++11,c++,开发语言)