C++深拷贝与浅拷贝(详解)

C++深拷贝与浅拷贝实现原理

一、简介

  • 在实际项目的开发过程中,哦们有时候需要用一个对象去初始化另一个对象,即原对象中的成员变量全部赋值给另一个成员变量。若采用系统默认的拷贝构造函数,就会存在浅拷贝的问题,会使得我们的程序出现一些问题。此时我们需要思考该怎么来解决这一问题呢?

  • 在《高质量的C++编程》中,作者有提到这样一段话:

    如果不主动编写拷贝构造函数和赋值函数,编译器将以"位拷贝"的方式自动生成缺省的函数,倘若勒种含有指针变量,那么两个缺省的函数就隐含了错误。以类string的两个对象为例,假设a.m_data的内容为"world",b中的内容为"hello"

    现在将a赋值给b,缺省赋值函数的"位拷贝"意味着执行b.m_data原有的呢村没被释放,造成内存泄漏;二是b.m_data和a.m_data指向同一块内存,a和b任何一个变动都会影响另一方;三是对象呗析构的时候,m-data被释放了两次

  • 上面一段话已经将浅拷贝的缺点说的很清楚了,下面做一下总结:

    1. 浅拷贝容易造成多个共用体公用一块内存,同一块内存资源释放多次,崩溃或者内存泄漏。

    2. 而深拷贝则会为每一个对象分配自己的内存空间,(特别是指在有指针成员的时候)但是深拷贝的拷贝构造函数是需要我们自己来编写的。

      所以在使用到拷贝构造函数的时候,就有必要使用到自己定义的拷贝构造函数。

二、如何解决浅拷贝带来的问题

  • 如上面已经提到的,解决浅拷贝的方法就是深拷贝了。
  • 下面用代码说话,请见例子:
#include <iostream>
using namespace std;
class TEST;
{
private:
    int *a;
    int len;
public:
    TEST(int *p,int n);
    ~TEST();
    void show();
}
TEST::TEST(int *p,int n)
{
    len = n;
    a = new char[8];	//自定义的拷贝构造函数中,需要为指针变量重新复制。
    for(int i = 0;i < n;i++)
    {
        a[i] = p[i];	//将A中值注意赋给P
    }
}
TEST::~TEST()
{
    delete []a;	//释放分配的空间
}

void TEST::show()
{
    cout << len << endl;
    for(int i = 0;i < len;i++)
    {
        if(a[i] != 0)
        cout << " " << a[i];
    }
}
int main(void)
{
    int b[] = {1,2,3,4,5,6,7};
    TEST A(b,88);
    A.show();
}

上面的拷贝构造函数不够正规,现在写一个常用的拷贝构造函数:

#include <iostream>
using namespace std;
class TEST;
{
private:
    int *a;
    int len;
public:
    TEST(int *p,int n);
    ~TEST();
    void show();
}
TEST::TEST(const TEST &T)
{
    len = T.len;
    a = new int[T.len];
    for(int i = 0;i < len;i++)
    {
        if(a[i] != 0)
            cout << a[i] << endl;
    }
}
TEST::~TEST()
{
    delete []a;	//释放分配的空间
}

void TEST::show()
{
    cout << len << endl;
    for(int i = 0;i < len;i++)
    {
        if(a[i] != 0)
        cout << " " << a[i];
    }
}
int main(void)
{
    int b[] = {1,2,3,4,5,6,7};
    TEST A(b,88);
    TEST B = A;
    A.show();
}

三、总结

可以看出,当一个类中有指针成员时,拷贝构造函数中必须要为该指针成员重新申请内存空间,即是说在堆区为他申请一块内存。即需要使用深拷贝。因为,若采用浅拷贝的话,原对象的改制真变量的地址,就会指向同一块内存区域,这样的话,其中一个对象改变了该指针所指向的数据后,另一个对象也会受到影响。

结论:若采用拷贝构造函数时最好自己编写一深拷贝构造函数。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值