拷贝构造函数 深拷贝&浅拷贝

拷贝构造函数是一种特殊的构造函数,用于在一个同类型对象的基础上生成一个新对象,他的函数形参列表有固定的写法(常量引用的形式)。

以二叉树节点的类Node为例:

class Node
{
public:
    int index;
    Node* left;
    Node* right;
public:
    Node(int i)   //构造函数,带一个参数
    {
        index=i;
        left=0;
        right=0;
    }
    Node()    //构造函数,不带参数
    {
        index=0;
        left=0;
        right=0;
    }
    Node(const Node& t)  //拷贝构造函数的特点是参数表是一个(const className&),t是自定义的变量名
    {
        this->index=t.index;
        left=0;
        right=0;
    }
}

拷贝构造函数以自己的一个同类对象为参数,生成一个新对象,比如:

Node t(10); //调用带一个参数的构造函数
Node x(t);  //调用拷贝构造函数

//另外当我们使用赋值号生成新的对象时,系统也是调用拷贝构造函数
Node y=t;  //等价于Node y(t);

总结就是:任何用自身同类对象生成新对象时,都会调用拷贝构造函数。

那么有一个问题,我刚刚说用赋值号的时候,系统会调用拷贝构造函数,那我没写拷贝构造函数,我难道不能用赋值号吗? 
答:如果没写拷贝构造函数,系统免费送一个默认的。这个默认的构造函数就是简单的把各个属性都对应复制一遍。

这种默认的拷贝构造函数,大部分情况下都没有问题,除非:成员变量里有指针!!! 
举个例子:

class Node
{
public:
    int* number
public:
    Node(const Node& t)   //默认的拷贝构造函数就这么干的
    {
        this->number=t.number;
    }
};

看看它干了啥!!!他把 t 的number里存的地址赋给了新对象的number,这意味着什么? 意味着新对象的number和t.number指着同一个空间,我在新对象里改了number所指空间的值,那么t.number指的空间值也就变了,这一般不是我们想要的,我们一般想要两个对象互不干扰,所以系统默认给的那种只是简单拷贝了指针地址的这种行为,我们叫浅拷贝,解决方法叫深拷贝,如下:

......
    Node(const Node& t)
    {
        number=new int();
        *number=*(t.number);
    }
......

也就是手动开辟一个新的空间给number,然后把t的number值拷贝进去,这样他们才是互相独立了。

所以当我们的类里存在指针成员变量的时候,又有要用到拷贝构造函数的时候,就要自己动手实现深拷贝。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值