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

  • 相关阅读:
    centos7.6 安装与配置 MongoDB yum方式
    MongoDB 介绍
    centos 关闭selinux
    前端 HTML标签属性
    前端 HTML 标签嵌套规则
    前端 HTML 标签分类
    前端 HTML body标签相关内容 常用标签 表单标签 form里面的 input标签介绍
    前端 HTML body标签相关内容 常用标签 表单标签 form 表单控件分类
    前端 HTML form表单标签 select标签 option 下拉框
    POJ 1426
  • 原文地址:https://www.cnblogs.com/kwdeblog/p/6144521.html
Copyright © 2011-2022 走看看