C++之深拷贝&浅拷贝

什么是拷贝构造函数?
通过拷贝对象的方式创建一个新的对象,拷贝构造函数的参数必须是类对象的引用,也就是将一个对象拷贝给另一个新建的对象(用途,在创建对象的时候,使用同一类之前创建的对象来初始化新创建的对象)

Book(Book &b);//必须是引用的原因是,如果是传值方式将实参传递给形参,中间要经历一个对象的拷贝,对象拷贝由必须调用拷贝构造函数,这样就形成一个死循环,无解

拷贝构造函数第一个参数一定是对象的引用,后面如果有其他参数,要给出默认值,否则就缺省不写

Book(Book &b,price = 5.0);

如果没有显示的声明一个拷贝构造函数,系统会自动为类生成一个拷贝构造函数,自动生成的仅仅将对象的所有成员变量复制给当前创建的对象(浅拷贝)
为了一个类中包含动态分配存储空间的指针类型的成员变量时,就必须为这个类设计一个拷贝构造函数,还要为他添加一个赋值操作符重载函数,重载(=)
为了不让对象发生拷贝行为,我们可以显示声明一个拷贝构造函数,并将其设置为private属性

什么是浅拷贝?
数据成员之间的简单复制,系统默认的拷贝构造函数实现的就是浅拷贝

默认的拷贝构造函数实现对数据成员一一赋值,但是如果类中含有指针类型的数据,这种拷贝只是将指针简单的拷贝,并没有分配新的内存

运算符“=”的重载就是实现浅拷贝的原因,由于对象之间含有指针数据类型,a , b恰好指向同一块内存,就是浅拷贝

当两个对象的指针指向同一块内存时,调用第一个的析构函数会释放一次内存,调用第二个又会把这个释放过的内存再次释放一次
对同一个动态内存释放两次以上结果时未定义的,容易导致内存泄露和程序崩溃。此时就需要深拷贝解决问题

注意:浅拷贝带来问题的本质在于析构函数释放多次堆内存,使用std::shared_ptr,可以完美解决这个问题。

什么是深拷贝?
为赋值对象申请了一个新的内存

当拷贝对象中有其他资源(堆)的引用时,对象另开辟一块新的资源,而不再对拷贝对象有其他资源的引用的指针或引用进行单纯的赋值

为了解决浅拷贝的问题,必须显示的定义拷贝构造函数,不但可以复制数据成员,还可以为对象分配各自的内存空间

深拷贝不仅对指针进行拷贝,对指针指向的内容也拷贝,也就是给对象新分配了一块内存,经过深拷贝后的指针是指向不同地址

对于普通成员的赋值,深拷贝浅拷贝都是一样的。

参见C++ primer第5版P448页

/* 深拷贝浅拷贝 */
#include<iostream>

using namespace std;

class A
{
public:
    A(int x) : data(x){}//构造函数初始化
    A(){}
public:
    int data;
};

class B
{
public:
    B(int x) : num(x){data = new int[num];}//构造函数初始化

    B(){};

    B(const B &X) : num(X.num){data = new int[num];}//深拷贝,增加了这一句拷贝构造函数,程序就不会崩溃

    ~B() {delete [] data;}
public:
    int *data;
    int num;
};



int main()
{
    A a(5);//用5初始化
    A b = a;//数据成员之间的赋值
    cout<< b.data<< endl;//输出为5
    cout<< a.data<< endl;//输出为5

    B c(5);//用5初始化
    B d = c;//对象拷贝,数据成员之间的赋值
    cout<< c.data<< endl;//输出为0x7ff5b9402a40
    cout<< d.data<< endl;//输出为0x7ff5b9402a40   指向了同一块内存,调用析构函数的时候造成内存泄露
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值