天天看点

C++面向对象编程,深浅拷贝

作者:黑猫编程

深浅拷贝

编译器默认提供的拷贝是浅拷贝,将一个对象中所有成员变量的值拷贝到另一个对象。

然而,如果某个对象成员是指针类型,只会拷贝指针中存储的地址值,并不会拷贝指针指向的内存空间。

当通过构造函数赋值时,类外部指针和类内部指针指向同一块内存空间,会相互干扰。

class Student {
private:
	char* m_name;
	int m_age;
public:
	Student(char* name, int age):m_name(name),m_age(age){}
	void output() {
		cout << m_name << " " << m_age << endl;
	}
	void changeName() {
		m_name[0] = 'x';
	}
};           
int main() {
	char name[10] = "blackcat";
	Student* stu1 = new Student(name, 10);
	stu1->output();
	cout << name << endl;

	stu1->changeName();

	stu1->output();
	cout << name << endl;
	return 0;
}           
C++面向对象编程,深浅拷贝

不仅两个指针可以相互修改内存数据,栈空间数据很可能会释放,导致堆空间指向数据消失。

解决方案

在堆空间再开辟一块内存,把栈空间数据拷贝过来,防止相互干扰。

Student(char* name, int age){
	m_name = new char[strlen(name) + 1]();
	strcpy(m_name, name);
	m_age = age;
}

~Student() {
	if (m_name == NULL) return;
	delete[] m_name;
	m_name = NULL;
}           
C++面向对象编程,深浅拷贝

拷贝构造问题

在堆空间备份栈空间数据,可以起到指针变量赋值时进行数据隔离。

然而,如果遇到拷贝构造会出现什么问题呢?

如果成员变量是指针类型,拷贝构造会导致多个对象保存同一个指针,不同对象的指针指向同一块内存空间,因此可以相互修改,并且析构时,会对同一块内存空间进行多次析构,使得程序发生异常。

C++面向对象编程,深浅拷贝

析构释放时会出现 double free 情况。

深拷贝

将原指针指向的内存空间拷贝一份到新的空间。

C++面向对象编程,深浅拷贝
private:
	char* m_name;
	int m_age;

	void copyName(const char* name) {
		if (name == NULL) return;
		m_name = new char[strlen(name) + 1]();
		strcpy(m_name, name);
	}           
public:
	Student(const char* name, int age) {
		copyName(name);
		m_age = age;
	}

	Student(const Student& stu) {
		copyName(stu.m_name);
		m_age = stu.m_age;
	}           

继续阅读