#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 ;
}
本文详细介绍了浅拷贝与深拷贝的概念,并通过C++实例展示了如何解决浅拷贝带来的问题。通过重新定义拷贝构造函数和等号运算符,实现深拷贝功能,确保对象间的独立性和资源的有效管理。
:深拷贝与浅拷贝及等号运算符重载&spm=1001.2101.3001.5002&articleId=49329345&d=1&t=3&u=a4234163630146039f4b9fc0fb8acdb2)
875

被折叠的 条评论
为什么被折叠?



