c++学习笔记(三):深拷贝与浅拷贝及等号运算符重载

#include<iostream.h>
#include<string.h>
//浅拷贝例子 没有自己写复制构造函数而是采用默认的复制构造函数

class name
{ public :
       name(char *pn) ;    
       ~ name() ;
   protected : 
       char *pname ;   
       int size ;
} ;
name :: name(char *pn)
 { 
 		cout <<" Constructing " << pn << endl ;
    pname = new char[strlen(pn)+1] ;
    if (pname!=0) 
    	strcpy(pname,pn) ;
    	size = strlen(pn) ;
 } 
name :: ~ name()
{ 
		cout << " Destructing " << pname << endl ; 
   	pname[0] = '\0' ;
  	 delete []pname ;
   	size = 0 ;
}

void main() 
 { 
 		name Obj1("NoName") ;
    name Obj2 = Obj1 ;
 }

创建Obj1对象时,开辟内存空间存放数据,而执行到 name Obj2 = Obj1 语句时,将Obj1对象复制给Obj2对象,因为没有构造拷贝构造函数,因此调用默认的拷贝构造函数,只是进行了浅拷贝
将Obj2对象指向Obj1对象的内存空间,而Obj2对象没有自身的内存空间,当程序调用Obj2对象的析构函数时,释放了其指向的内存空间即Obj1对象开辟的内存空间。而当Obj1对象析构时,因为Obj2对象已经将其内存空间析构掉了,所以程序执行到此处将崩溃掉。


  解决浅拷贝带来的问题的方法就是:重新构造一个拷贝构造函数,在函数中重新开辟一段内存空间为Obj2对象所用

 
name::name(const name &Obj)
{ 
	cout << " Copying " << Obj.pname << " into its own block\n" ;
  pname = new char[strlen(Obj.pname)+1] ;
  if (pname!=0) 
  	strcpy(pname, Obj.pname) ;
  	size = Obj.size ;
}
/*
	接着上一步之后又重新创建了一个Obj3对象并采用等号运算符赋值给Obj2(注意:此时是先创建Obj3对象,两条语句赋值)

*/
void main() 
 { 
 		name Obj1("NoName") ;
    name Obj2 = Obj1 ;
    name Obj3("obj3...");

	//重载=号操作符
	Obj2 = Obj3; //=号操作
 }


        程序执行完此name Obj2 = Obj1 后  ,Obj1与Obj2由于调用了自己写的构造函数因此,Obj1与Obj2都有自己的内存空间,然后程序继续执行,创建Obj3对象,分配内存空间,
 而执行到Obj2 = Obj3语句时,因为是等号运算符,编译器会调用默认的拷贝构造函数,进行了浅拷贝,产生了与上面的同样的问题,Obj2 与Obj3指向了统一内存空间。使程序崩溃。
 

        解决等号运算符与浅拷贝带来的问题的方法就是:重载等号运算符,在函数中重新开辟一段内存空间为Obj2对象所用,但是由于之前Obj2已经开辟了内存空间为了防止内存泄露,需要先对内存空间进行释放,然后在重建新的内存空间。

void name::operator=(Name &obj3)
	{
		if (pname != NULL)
		{
			 delete []pname;
			pname = NULL;
			size = 0;
		}
		cout<<"测试有没有调用我。。。。"<<endl;

		  pname = new char[strlen(Obj.pname)+1] ;
  if (pname!=0) 
  	strcpy(pname, Obj.pname) ;
  	size = Obj.size ;

	}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值