📅  最后修改于: 2023-12-03 15:29:43.015000             🧑  作者: Mango
在C++中,当我们定义一个类对象并将其赋值给另一个对象时,会发生复制。然而,不同的复制方式会导致不同的结果。本文将介绍C++中的两种复制方式:浅复制和深复制。
浅复制是指只复制对象的值,而不复制指向对象的指针或引用。这意味着如果一个对象的某个成员指向堆上的内存,那么复制这个对象只会复制它的地址,而不会复制指向的内存。
下面是一个例子:
#include<iostream>
using namespace std;
class ShallowCopy {
public:
ShallowCopy(int size) {
m_data = new int[size];
m_size = size;
}
~ShallowCopy() {
delete[] m_data;
}
void setValue(int index, int value) {
m_data[index] = value;
}
void printData() {
for(int i = 0; i < m_size; ++i) {
cout << m_data[i] << " ";
}
cout << endl;
}
private:
int* m_data;
int m_size;
};
int main() {
ShallowCopy source(5);
source.setValue(0, 1);
source.setValue(1, 2);
source.setValue(2, 3);
source.printData();
ShallowCopy copy = source; // 浅复制
copy.setValue(0, 10);
copy.printData(); // 输出:10 2 3
source.printData(); // 输出:10 2 3
return 0;
}
在上面的代码中,我们定义了一个ShallowCopy类,它包含一个指向堆上整型数组的指针。在main函数中,我们先定义了一个source对象,然后对它进行了一些操作(修改了前三个元素的值),并打印了它的所有元素。接着,我们定义了一个copy对象,将source对象赋值给它。这时,copy对象和source对象的m_data指向同一个堆对象,即它们共享同一片内存。我们在copy对象中修改了第一个元素的值为10,然后分别打印了copy对象和source对象的所有元素。可以看到,两个对象的第一个元素都被修改了。
这里的关键问题是,由于浅复制只复制了指针m_data的地址,而没有复制它所指向的堆内存,所以当我们修改copy对象中的m_data时,source对象的m_data也会被修改。
深复制是指在复制对象时,不仅要复制对象的值,还要复制对象指向的所有内存。深复制会为新对象分配一块新的内存,然后将指针或引用指向这个新的内存。这样,新对象和原对象就不再共享一片内存。
下面是一个例子:
#include<iostream>
using namespace std;
class DeepCopy {
public:
DeepCopy(int size) {
m_data = new int[size];
m_size = size;
}
~DeepCopy() {
delete[] m_data;
}
DeepCopy(const DeepCopy& other) { // 深复制构造函数
m_size = other.m_size;
m_data = new int[m_size];
for(int i = 0; i < m_size; ++i) {
m_data[i] = other.m_data[i];
}
cout << "DeepCopy constructor is called." << endl;
}
void setValue(int index, int value) {
m_data[index] = value;
}
void printData() {
for(int i = 0; i < m_size; ++i) {
cout << m_data[i] << " ";
}
cout << endl;
}
private:
int* m_data;
int m_size;
};
int main() {
DeepCopy source(5);
source.setValue(0, 1);
source.setValue(1, 2);
source.setValue(2, 3);
source.printData();
DeepCopy copy = source; // 深复制
copy.setValue(0, 10);
copy.printData(); // 输出:10 2 3
source.printData(); // 输出:1 2 3
return 0;
}
在上面的代码中,我们定义了一个DeepCopy类,并额外定义了一个深复制构造函数。在main函数中,我们定义了一个source对象,并对它进行了一些操作(同样是修改前三个元素的值)。接着,我们定义了一个copy对象,并将source对象赋值给它。这时,copy对象和source对象都拥有了自己的内存空间,它们互不干扰。我们在copy对象中修改了第一个元素的值为10,然后分别打印了copy对象和source对象的所有元素。可以看到,copy对象的第一个元素被修改了,而source对象的元素没有变化。
这里的关键问题是,由于深复制为copy对象分配了一块新的内存空间,并将source对象的数据全部复制到它的内存空间中,所以当我们修改copy对象中的数据时,它不会影响到source对象。
C++中的复制方式有两种:浅复制和深复制。浅复制只复制对象的值,而不复制指向对象的指针或引用;这造成了对象之间的共享内存。而深复制则会为新对象分配一块独立的内存空间,然后将原对象的数据全部复制到其中,从而使它们互不干扰。在实际应用中,我们需要根据情况来选择不同的复制方式,以保证程序的正确性和可靠性。