您的位置:首页 > 编程语言 > C语言/C++

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

2015-10-22 09:44 477 查看
#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 ;

}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: