C++深拷贝与浅拷贝
1.定义:
我们对一个已知对象拷贝时,编译系统会自动调用一种拷贝构造函数——拷贝构造函数,如果用户未定义拷贝构造函数,
则会默认调用拷贝构造函数
浅拷贝,是由缺省的拷贝构造函数所实现的数据成员逐一进行赋值,如果类中含有指针则会产生错误。
为了解决浅拷贝出现的错误,我们可以定义一个拷贝构造函数,使之不仅仅拷贝数据成员,为对象1和对象2分配各自
的内存空间。这就是所谓的深拷贝
简单来说:浅拷贝拷贝的是指针变量地址,深拷贝会重新开辟内存空间。
2.示例
我们用一个例子来了解一下拷贝构造的去浅拷贝和深拷贝:
我们对student对象进行浅拷贝,对象包含指针
#include<iostream> using namespace std; class Student { private: char* name; int age; public: Student() { name = new char(20); cout << "Student" << endl; } ~Student() { cout << "destroy Student!" << endl; delete name; //这里会delete两次,第二次程序会直接崩掉 name = NULL; } }; int main() { Student s1; Student s3(s1); return 0; }
代码执行结果:
我们发现在拷贝构造时候,在函数析构时后程序崩掉了。
此时我们调用了两次析构函数,指针所指的内存释放了两次!但我们构造函数指针只分配了一次内存
造成了内存泄漏
我们发现对存在指针的对象进行浅拷贝后会出现两个指针指向同一个内存空间的情况
所以我们为了避免内存泄漏对含有指针成员的对象进行拷贝时,必须要自己定义拷贝构造函数,使拷
贝后的对象指针成员有自己的内存空间,这就是深拷贝的方式。(还可以引入引用技术设计或智能指
针,后边博客会讲道)
深拷贝代码:
#include<iostream> #include<string.h> using namespace std; class Student { char* name; int age; public: Student(); ~Student(); Student(const Student& s); }; Student::Student() { name = new char(20); cout << "Build Student" << endl; } Student::~Student() { cout << "destory Student" <<(int)name<<endl; delete name; name = NULL; } Student::Student(const Student& s) { name = new char(20); memcpy(name, s.name, strlen(s.name)); //同时将内存地址也拷贝过去 cout << "copy Student" << endl; } int main() { Student stu1; Student stu2(stu1); return 0; }
代码执行结果:
深拷贝经过一次构造函数,一次自定义拷贝构造函数,两次析构函数。且两个对象的指针成员所指内存不同,我们最终完成了
对指针进行的拷贝构造