C++ 深拷贝和浅拷贝
当类的函数成员存在__指针成员__时会产生深拷贝和浅拷贝和问题。
在进行对象拷贝时会使用默认拷贝构造函数,默认进行浅拷贝,即只会拷贝指针的值,新拷贝的指针与原来的指针指向同一内存;
浅拷贝带来的问题是,调用析构函数时,会导致堆内存被多次释放,因为这些指针指向的是同一份内存。
深拷贝会对指针指向的内存也进行拷贝,解决了指针悬挂的问题。
关于类对象拷贝的情况,需要注意:
- 当函数的参数为对象,实参传递给形参的时候,或函数返回值为一个对象,函数内对象传递给返回值时,系统均通过拷贝构造函数实现。
- 浅拷贝带来的隐患是,多次释放指向同一块堆内存的不同指针时,会造成内存多次释放的问题。可以使用智能指针
std::shared_ptr
解决这个问题。
Example
#include <iostream>
using namespace std;
class Randy {
private:
int age;
char *id;
public:
Randy();
~Randy();
};
Randy::Randy() { id = new char(10); }
Randy::~Randy() {
delete id;
id = nullptr;
}
int main() {
{
Randy q1;
Randy q2(q1);
}
return 0;
}
运行该程序:
(base) qiancj@SanJieJiYuan:~/codes/test$ ./randy
free(): double free detected in tcache 2
Aborted (core dumped)
增加深拷贝 拷贝构造函数
#include <iostream>
#include <cstring>
using namespace std;
class Randy {
private:
int age;
char *id;
public:
Randy();
~Randy();
Randy(const Randy &randy);//拷贝构造函数,const防止对象被改变
};
Randy::Randy() {
id = new char(13);
cout << "Randy ctor" << endl;}
Randy::~Randy() {
cout << "~Randy : delete id " << id << endl;
delete id;
id = nullptr;
}
Randy::Randy(const Randy &randy)
{
age = randy.age;
id = new char(13);
// 内存拷贝
memcpy(id, randy.id, strlen(randy.id));
cout << "deep copy Randy" << endl;
}
int main() {
{
Randy q1;
Randy q2(q1);
}
return 0;
}
运行结果:
(base) qiancj@SanJieJiYuan:~/codes/test$ ./randy
Randy ctor
deep copy Randy
~Randy : delete id
~Randy : delete id
欢迎关注公众号【三戒纪元】