zoukankan      html  css  js  c++  java
  • c++中拷贝构造函数,浅拷贝和深拷贝的区别,以及移动构造函数总结

       一、构造函数、浅拷贝和深拷贝

    在C++提供了一种特殊的构造函数,称为拷贝构造函数。拷贝构造函数具有一般构造函数的所有特性,其作用是使用一个已经存在的对象(由拷贝构造函数的参数指定的对象)去初始化一个新的同类对象,即完成本类对象的复制。程序员如果没有定义拷贝构造函数,系统会自动生成一个默认的拷贝构造函数,其功能是把已存在的每个数据成员都复制到新对象中。程序员定义拷贝构造函数时,一般形式:

      类名(类名 & 对象)

        {

        }

        拷贝构造函数在三种情况下会被自动调用

        (1)用一个对象去初始化一个同类的对象  XX B(A)

     (2) XX aa = a,当一个新对象被定义的时候,即便这个时候是使用了'='运算符,它真实调用的是初始化函数copy constructor,而不是调用copy assignment operator去进行赋值操作。;

        (3)如果函数的形参是对象,进行形参和实参结合时,调用拷贝构造函数。f(A);

        (4)如果函数的返回值是对象,返回主调函数时,调用拷贝构造函数。 XX B=g();

      其中默认的拷贝构造函数是浅拷贝。当类的数据成员有指针类型是,假设同类对象A初始化B,A和B对象使用同一内存区域。在撤销对象时,导致对这一内存的两次释放,也就是说浅层复制:只复制指向对象的指针,而不复制引用对象本身。这时候要求程序员编制拷贝构造函数,使对象B的指针指向另外的内存区域,这叫深拷贝,深层复制:复制引用对象本身。

       二、移动构造函数

       右值引用,临时值,如果是临时值,不调用深拷贝,而是移动构造函数(move construct),来提升性能。

    #include<iostream>
    using namespace std;
    class Test{
    public:
        Test() :x(0) 
        { 
            cout << "构造函数 this = " << this << endl; 
        }
        Test(int x) :x(x) 
        { 
            cout << "构造函数 this = " << this << endl;
        }
        Test(const Test& another) :x(another.x) 
        { 
            cout << "拷贝构造函数 this = " << this << " from " << &another << endl; 
        }
        Test(const Test&& another) : x(another.x)
        { 
            cout << "移动构造函数 this = " << this<< " from " << &another << endl; 
        }
        ~Test() 
        { 
            cout << "析构函数 this = " << this << endl; 
        }
        friend ostream& operator<<(ostream& out, const Test &t);
    private:
        int x;
    };
    
    //运算符重载
    ostream& operator<<(ostream& out, const Test &t){
        out << "&t = " << &t << ",x = " << t.x;
        return out;
    }
    
    Test maketest()
    {
        Test x(4);
        cout << "hell" << endl;
        return x;
    }
    int main()
    {
        //测试拷贝构造函数
        Test test(3);
        cout << test << endl;
        Test test2(test);
        cout << test2 << endl;
        cout << endl;
        //测试移动构造函数
        Test first = maketest();//有一个临时对象,
        cout << first << endl;
        cout << endl;
        system("pause");
    }
        //测试移动构造函数1
        Test first = maketest();//有一个临时对象,
        /*
        测试1结果分析:正常情况下直接调用拷贝构造函数,如果定义了移动构造函数,
        则直接调用移动构造函数。
        */
        //测试移动构造函数2
        //Test first;//有一个临时对象,
        //first = maketest();
        /*
        测试2结果分析:正常情况下,是调用拷贝构造函数,然后调用赋值构造函数,
        但如果定义了移动构造函数,就是调用移动构造函数,然后调用赋值构造函数。
        */

    输出结果:

     如果没有移动构造函数,可以看结果:

     用的拷贝构造函数,但拷贝构造函数有性能损失,可以参考

    https://blog.csdn.net/weiqing00/article/details/80929788

  • 相关阅读:
    Gym
    数学公式头文件
    除法取模(比赛常用)
    ACM-ICPC 2017 Asia Urumqi A. Coins【期望dp】
    P1494 小Z的袜子 【普通莫队】
    Codeforces Round #642 (Div. 3) E—K-periodic Garland dp
    luogu P4568 [JLOI2011]飞行路线 最短路Dijkstra+dp
    luogu P2015 二叉苹果树 树形dp
    luogu P1462 通往奥格瑞玛的道路 二分+spfa
    luogu P1879 [USACO06NOV]Corn Fields G 状态压缩dp
  • 原文地址:https://www.cnblogs.com/kwdeblog/p/6144521.html
Copyright © 2011-2022 走看看