• 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;
    }
    

      

  • 相关阅读:
    Suricata的输出
    Setting up IPS/inline for Linux in Suricata
    Suricata的初始化脚本
    Suricata的Reputation
    Suricata的配置
    Suricata的性能
    Suricata里的规则与Snort区别之处
    Suricata的命令行解释
    [转]ASP.NET 成员资格 Part.1(API)
    [转]ASP.NET MVC4+BootStrap 实战(一)
  • 原文地址:https://www.cnblogs.com/freebird92/p/9728618.html
Copyright © 2020-2023  润新知