js深拷贝和浅拷贝概念(对象的浅拷贝和深拷贝问题)
导读:先看示例代码 点击查看代码 #include...
先看示例代码
点击查看代码 #include <iostream> #include<cstring> using namespace std; class Student{ public: Student(int _age , const char * _name) { this->age=_age; int len=strlen(_name)+1; char *tep=new char[len]; this->pName=tep; strcpy(this->pName,_name); } ~Student(){ delete[]this->pName; this->pName=nullptr; } void showStudent(){ cout<<this->pName<<" "<<this->age<<endl; } private: int age; char *pName; }; int main(){ Student s1(20,"zhangsan"); s1.showStudent(); Student s2=s1; s2.showStudent(); return 1; }上面示例代码中,对象的默认拷贝方式是内存数据拷贝,如果对象占用了外部资源 ,那么就会出现问题了,这里的外部资源
就是在堆上申请的空间存放名字用,
s1,s2两个对象中的名字指针都是指向了同一块堆内存区域,在结束main函数的是,s2先析构,s2会析构调堆上的内存空间,
s1再析构,由于s1对象的pName 指针和s2对象的pName指针指向的是同一块堆内存区域,但是该区域内存已经被释放了,所以遇到了问题鉴于上面的问题,我们引出了 浅拷贝,深拷贝的问题和解决方法.
Student s2=s1; 会调用拷贝构造函数(该拷贝构造函数可以是系统自动生成的,或者你自己定义一个拷贝构造函数)
系统自动生成的拷贝构造函数做的是内存数据拷贝,所以就出现了上面的问题.因此我们需要定义属于自己的拷贝构造函数改造代码如下
点击查看代码 class Student2{ public: Student2(int _age , const char * _name) { this->age=_age; int len=strlen(_name)+1; char *tep=new char[len]; this->pName=tep; strcpy(this->pName,_name); cout<<"执行构造函数"<<endl; } //自定义拷贝构造函数 Student2(const Student2 &_stu2){ this->age=_stu2.age; int len =strlen(_stu2.getPName())+1; char *newPName =new char[len]; this->pName=newPName; strcpy(this->pName,_stu2.getPName()); cout<<"执行拷贝构造函数"<<endl; } ~Student2(){ if(this->pName!=nullptr){ delete[]this->pName; this->pName=nullptr; } } void showStudent(){ int *p=(int *)this->pName; cout<<this->pName<<" "<<this->age<<" pName Heap Address ="<<p<<endl; } const char * getPName() const{ return this->pName; } private: int age; char *pName; }; int main(){ Student2 s1(20,"zhangsan"); s1.showStudent(); Student2 s2=s1; s2.showStudent(); return 1; }上面的代码还存在一个问题如下 ,如果在main函数中是下面的代码
Student2 s1(20,"zhangsan");
Student2 s2(30,"lisi");
s2=s1;
在main函数结束的是同样会遇到问题,这个时候就引出 赋值函数 ,我们需要定义自己的赋值函数
在 s2=s1这一段代码其实是这样调用的
s2.operator=(s1)在你不定义自己的赋值函数的时候,系统会帮我们生成一个赋值函数,该赋值函数的赋值方式就是内存的数值拷贝,这种方式
在Student对象,会有问题,所以我们需要向自定义拷贝构造一样,定义一个属于自己的赋值函数代码如下
点击查看代码 class Student3{ public: Student3(int _age , const char * _name) { this->age=_age; int len=strlen(_name)+1; char *tep=new char[len]; this->pName=tep; strcpy(this->pName,_name); cout<<"执行构造函数"<<endl; } //自定义拷贝构造函数 Student3(const Student3 & _stu){ this->age=_stu.age; int len =strlen(_stu.getPName())+1; char *newPName =new char[len]; this->pName=newPName; strcpy(this->pName,_stu.getPName()); cout<<"执行拷贝构造函数"<<endl; } //自定义赋值函数 Student3 & operator= (const Student3 & _stu){ //防止自赋值 if(this==&_stu){return *this;} //注意: 需要先释放当前的堆内存空间!! delete []this->pName; this->age=_stu.age; int len =strlen(_stu.getPName())+1; char *newPName =new char[len]; this->pName=newPName; strcpy(this->pName,_stu.getPName()); cout<<"执行赋值函数"<<endl; return *this; } ~Student3(){ if(this->pName!=nullptr){ delete[]this->pName; this->pName=nullptr; } } void showStudent(){ int *p=(int *)this->pName; cout<<this->pName<<" "<<this->age<<" pName Heap Address ="<<p<<endl; } const char * getPName() const{ return this->pName; } private: int age; char *pName; }; int main(){ Student3 s3(20,"zhangsan"); s3.showStudent(); Student3 s4(30,"lisi"); s4=s3; s4.showStudent(); return 1; }运用深拷贝浅拷贝实现String 代码如下
点击查看代码 #include <iostream> #include <cstring> using namespace std; class MyString{ public: //构造函数 MyString(const char * src){ //创建空串 if(src==nullptr){ this->pchar=new char[1]; this->pchar[0]=\0; } else{ int len =strlen(src)+1; this->pchar=new char[len]; strcpy(this->pchar,src); } cout<<"执行构造函数, 堆内存空间地址"<<(int *)this->pchar <<endl; } //拷贝构造 MyString(const MyString & myString){ //重新分配内存空间 int len =myString.stringLen()+1; this->pchar=new char[len]; strcpy(this->pchar,myString.pchar); cout<<"执行拷贝构造函数, 新创建堆内存空间地址"<<(int *)this->pchar <<endl; } //赋值函数 MyString & operator=(const MyString & myString){ //防止自赋值 if(this==&myString){return *this;} //释放现有的堆内存空间 delete[]this->pchar; this->pchar=nullptr; int len =myString.stringLen()+1; this->pchar=new char[len]; strcpy(this->pchar,myString.pchar); cout<<"执行赋值函数, 新创建堆内存空间地址"<<(int *)this->pchar <<endl; return *this; } int stringLen() const { return strlen(this->pchar); } //析构 ~MyString(){ delete [] this->pchar; this->pchar=nullptr; } void printChar() const{ cout<<this->pchar<<endl; } private: char *pchar; }; int main(){ MyString s1("abcd"); s1.printChar(); MyString s2=s1;//执行拷贝构造 s2.printChar(); MyString s3("1234"); s3=s1;//执行赋值函数 s3.printChar(); return 1; }创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!