简介:···················
引入动态内存分配,浅拷贝所出现的问题:
//当所创建的类中涉及到动态内存的分配数据时,相应的,深拷贝也就出现了。 #include<iostream> using namespace std; class MyStu{ int id; int age; char *name; public: MyStu(int id,int age){ this->id = id; this->age = age; this->name = new char[125]; } ~MyStu(){ if (name){ delete[] name; } } }; int main(){ //拷贝构造两种调用方式:显示调用,以及隐式调用 cout << "----------------------" << endl; cout << "类的拷贝构造(浅拷贝)" << endl; MyStu s(1,20);//调用带参构造 MyStu s1(s);//显示调用拷贝构造 MyStu s2 = s1;//隐式调用拷贝构造 return 0; }
控制台结果:
以下的图是针对对象建立的模块图:
- MyStu s(1,20);//调用带参构造
- MyStu s1(s);//显示调用拷贝构造(如果使用默认的拷贝构造,当类的数据成员指向堆区内存的时候,会拷贝指针,但不会拷贝堆内存(浅拷贝)----所以在析构的时候,第一次s1析构完后,紧接着s2析构就会出现问题)
)
自定义拷贝来解决浅拷贝的问题(深拷贝)----》深拷贝要通过引用传递的方式来构造拷贝函数,并且因为拷贝的是相同数据,所以它的数据不允许更改,因此要在构造函数的引用类型前加上const.
//当所创建的类中涉及到动态内存的分配数据时,相应的,深拷贝也就出现了。 #include<iostream> using namespace std; class MyStu{ int id; int age; char *name; public: //MyStu(MyStu other);//编译出错,在编译时会导致死循环编译----值传递 //MyStu(MyStu *other);//不满足拷贝构造的定义:用自身这种类型的数据来构造自身。--址传递 MyStu(const MyStu& other);//因为拷贝的数据不允许更改,所以要在引用前加上const常量。 MyStu(int id,int age){ this->id = id; this->age = age; this->name = new char[125]; strcpy(name,"zhangshan"); } ~MyStu(){ //没有动态内存,可以不写。 if (name){ delete[] name; } } }; MyStu::MyStu(const MyStu& other){ this->id = other.id; this->age = other.age; if (other.name){ int len = strlen(other.name); this->name = new char[len+1]; strcpy(name, other.name); } else name = NULL;//这个操作就是深拷贝 } int main(){ //拷贝构造两种调用方式:显示调用,以及隐式调用 cout << "----------------------" << endl; cout << "类的拷贝构造(浅拷贝)" << endl; MyStu s(1,20);//调用带参构造 MyStu s1(s);//显示调用拷贝构造 MyStu s2 = s1;//隐式调用拷贝构造 return 0; }
控制台结果,没有错误:
深拷贝逻辑结构图:(拷贝了指针,也拷贝了堆内存)