C++之一些事一些情--深拷贝和浅拷贝

1、拷贝构造函数的出现场景

       以下是String类的一个简单定义,用于说明一些例子:

class String
{
public:
    String(const char *ch=NULL);		//默认构造函数
    String(const String &str);			//拷贝构造函数
    ~String(void);				//析构函数
    String& operator=(const String &str);	//赋值构造函数

private:
    char *m_data;
};

       当用一个已初始化的类类型对象初始化一个新的对象时,拷贝构造函数就会被调用,拷贝构造函数会出现在以下三种情景:


1) 一个对象以值传递的方式传入函数体

void InputString(String obj)
{
    //函数具体逻辑
}

2) 一个对象以值传递的方式从函数返回

String OutputString()
{    
    return String("hello world");
}

3) 使用一个对象初始化另一个对象

String a(1);
String b = a;	//通过对象a初始化对象b


2、深拷贝和浅拷贝的区别

       深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。
       当用户没有自定义拷贝构造函数时,编译器会自动生成一个默认的拷贝构造函数,并以位拷贝(位拷贝就是浅拷贝)的方式完成对象之间的赋值。关于深拷贝和浅拷贝的一个经典例子就是String类的实现,以下代码使用一个String类对象初始化另一个String类对象:

String a("Shallow Copy");
String b = a;

       若上面的代码没有重写拷贝构造函数,就会出现以下的问题:
       1) 对象a和对象b的成员变量m_data将会指向了同一内存区域,其中一方的改变将会影响另一方;
       2) 当对象析构的时候,对象a的成员变量m_data将会被析构两次,造成程序崩溃。


3、拷贝构造函数和赋值构造函数

       所谓赋值构造函数,就是操作符"="的重载函数,它的作用与拷贝构造函数类似,若没有重写赋值构造函数,编译器也会自动生成一个默认的以位拷贝工作的赋值构造函数。

String a("hello");
String b("world");
b = a;

       若上面的代码没有重写赋值构造函数,则会出现以下问题:
       1) 对象b的成员变量m_data原来指向的内存区域没有被释放,造成内存泄露;
       2) 对象a和对象b的成员变量m_data将会指向了同一内存区域,其中一方的改变将会影响另一方
       3) 当对象析构的时候,对象a的成员变量m_data将会被析构两次,造成程序崩溃。

       不是说有等于号的时候就是赋值构造函数,有的时候拷贝构造函数和赋值构造函数容易混淆,看以下例子:

String a("hello");
String b("world");
String d = a;	//拷贝构造函数
b = a;		//赋值构造函数

       当用一个已存在的对象初始化一个未存在的对象时,调用的是拷贝构造函数;当用一个已存在的对象给另一个已存在的对象赋值时,调用的是赋值构造函数,它也仅出现在这种情况。
       为了设计出更安全的类,需要使用到拷贝构造函数和赋值构造函数时,则重写一个深拷贝的版本;若不需要,则禁用这两个函数,免得出现一些不应该的错误。只要对拷贝构造函数和赋值构造函数的函数访问级别设置为private即可以禁用这两个函数,以前面的String简单定义代码为例子:

class String
{
public:
    String(const char *ch=NULL);		//默认构造函数
	~String(void);						//析构函数

private:
    String(const String &str);				//拷贝构造函数
    String& operator=(const String &str);	//赋值构造函数

private:
    char *m_data;
};


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值