c++ 11 移动语义

C++ 已经拥有了拷贝构造函数, 和赋值函数,它们主要定位为浅和深度拷贝, 新增加一个移动构造函数,主要避免拷贝构造。

在定义了移动构造函数的情况下,在实参(argument)是一个右值(rvalue,包括xvalue和prvalue)的情况下会调用移动构造函数,而不是调用复制构造函数 

可以使用std::move语句可以将左值变为右值而避免拷贝构造,修改代码如下:

编译器会对返回值进行优化,简称RVO,是编译器的一项优化技术,它涉及(功能是)消除为保存函数返回值而创建的临时对象。

-fno-elide-constructors,此选项作用是,在 g++ 上编译时关闭 RVO。

shell> g++ main.cpp -std=c++11 -fno-elide-constructors

#include <iostream>
using namespace std;

class Test
{
public:
    Test(int a = 0)
    {
        d = new int(a);
        cout << "cs" << this <<endl;
    }

    Test(const Test & tmp)
    {
        d = new int;
        *d = *(tmp.d);
        cout << "copy
";
    }

//    Test(Test && tmp)
//    { // 移动构造函数
//        d = tmp.d;
//        tmp.d = NULL; // 将临时值的指针成员置空
//        cout << "mv" << this << endl;
//    }

    ~Test()
    {
        if(d != NULL)
        {
            delete d;
            cout << "delete d
";
        }
        cout << "ds: " << this << endl;
    }

    int * d;
};

Test GetTmp()
{
    Test h;
    cout << "Resource from " << __func__ << ": " << (void *)h.d << endl;
    return h;
}

int main()
{
    //Test&& obj = GetTmp();
    Test obj = GetTmp();
    cout << "Resource from " << __func__ << ": " << (void *)obj.d << endl;

    return 0;
}

  

 

 

  使用移动语义后

#include <iostream>
using namespace std;

class Test
{
public:
    Test(int a = 0)
    {
        d = new int(a);
        cout << "cs" << this <<endl;
    }

    Test(const Test & tmp)
    {
        d = new int;
        *d = *(tmp.d);
        cout << "copy
";
    }

    Test(Test && tmp)
    { // 移动构造函数
        d = tmp.d;
        tmp.d = NULL; // 将临时值的指针成员置空
        cout << "mv" << this << endl;
    }

    ~Test()
    {
        if(d != NULL)
        {
            delete d;
            cout << "delete d
";
        }
        cout << "ds: " << this << endl;
    }

    int * d;
};

Test GetTmp()
{
    Test h;
    cout << "Resource from " << __func__ << ": " << (void *)h.d << endl;
    return h;
}

int main()
{
    Test&& obj = GetTmp();
    cout << "Resource from " << __func__ << ": " << (void *)obj.d << endl;

    return 0;
}

  

 

  

int main()
{
    //Test&& obj = GetTmp();
    Test obj = GetTmp();
    cout << "Resource from " << __func__ << ": " << (void *)obj.d << endl;

    return 0;
}

  

原文地址:https://www.cnblogs.com/freebird92/p/9728618.html