• 移动构造函数


       C++03 性能上被长期被诟病的其中之一,就是其耗时且不必要的深度拷贝。深度拷贝会发生在当对象是以传值的方式传递。举例而言,std::vector<T> 是内部保存了C-style 数组的一个包装,如果一个std::vector<T>的临时对象被建构或是从函数返回,要将其存储只能通过生成新的std::vector<T>并且把该临时对象所有的数据复制进去。该临时对象和其拥有的内存会被摧毁。

      而有了右值引用后,就可以直接使用右值引用的指针值,无需再重新分配内存和拷贝了。

      这里,举一个赋值构造函数和移动构造函数的例子。Person类有三个构造函数,定义如下。

    class Person {
    public:
        Person(int p) { 
            num = new int;
            *num = p;
        };
        Person(Person& rhs) ;//赋值构造函数
        Person(Person&& rhs) ;//移动构造函数
        ~Person() { 
            if (num) { 
                delete num; 
            } 
        };
    private:
        int *num = NULL;
    };

       赋值构造函数,使用深度拷贝进行赋值。

    Person::Person(Person& rhs) {
        cout << "copy constructor" << endl;
        if (num) {
            delete num;
        }
        num = new int;
        *num = *rhs.num;
    }

      右值引用定义为T&&,这样我们可以把右值的内存直接拿过来而不需要重新申请内存。在将右值引用rhs的指针num赋值给当前实例后,需要将右值引用的指针num赋值为nullptr,这样离开当前作用域后右值引用的num指针就不会被释放。这样就有效的减少了深度拷贝导致的内存与效率浪费。

    Person::Person(Person&& rhs) {
        cout << "move copy constructor" << endl;
        if (this != &rhs) {
            if (num) {
                delete num;
            }
            num = rhs.num;
            rhs.num = nullptr;//这样rhs析构的时候不会释放num
        }
    }

       实际应用如下,Person(4)作为一个右值引用初始化p3,有效的减少了深度拷贝造成的资源浪费。

    void testPerson() {
        Person p1(3);
        Person p2(p1);
        Person p3(Person(4));
        Sleep(0);
    }
  • 相关阅读:
    什么是IO多路复用
    Coursera, Machine Learning, Unsupervised Learning, K-means, Dimentionality Reduction
    Coursera, Machine Learning, SVM
    ShareSDK
    iOS JS和OC交互
    iOS KVO 常见错误
    第三方框架之SDWebImage
    单例存储账号
    UIRefreshControl
    二维码扫描
  • 原文地址:https://www.cnblogs.com/chenyangchun/p/7840042.html
Copyright © 2020-2023  润新知