c++ の浅いコピーと深いコピーの実装方法
オブジェクトのコピー処理においては、シャローコピーとディープコピーがあります。
浅いコピーとは、オブジェクトの値のみをコピーして、オブジェクトが指すメモリはコピーしないことをいいます。この場合、コピーしたオブジェクトと元のオブジェクトで同じメモリを指すポインタを持ちます。コピーしたオブジェクトと元のオブジェクトが指すメモリが解放されると、2つのオブジェクトは同じ無効メモリを指すことになり、プログラムに障害を起こす可能性があります。
얕은 복사를 구현하는 방법은 크게 두 가지입니다.
- オブジェクトの値をビット単位でコピーするデフォルトのコピーコンストラクタと代入演算子。この方式で実行されるコピーは、シャローコピーです。
class MyClass {
public:
int *data;
int size;
// 默认的拷贝构造函数
MyClass(const MyClass& other) {
size = other.size;
data = other.data;
}
// 默认的赋值运算符
MyClass& operator=(const MyClass& other) {
if (this != &other) {
size = other.size;
data = other.data;
}
return *this;
}
};
- 複製コンストラクタと代入演算子をカスタマイズすると、特定の複製操作を実装する必要がある場合に、浅い複製を実行できます。
class MyClass {
public:
int *data;
int size;
// 自定义的拷贝构造函数
MyClass(const MyClass& other) {
size = other.size;
data = other.data;
}
// 自定义的赋值运算符
MyClass& operator=(const MyClass& other) {
if (this != &other) {
size = other.size;
data = other.data;
}
return *this;
}
};
ディープコピー:オブジェクトをコピーする際、新しいメモリを再割り当てし、元のオブジェクトが指し示すメモリの内容を新しいメモリにコピーします。つまり、コピーオブジェクトと元のオブジェクトに同じメモリを指し示すポインタがないため、コピーオブジェクトを変更しても元のオブジェクトに影響を与えません。
ディープコピーを実現するための主な方法は 2 つしかありません。
- 自前のコピーコンストラクタ・代入演算子を定義する際には、新しいメモリを手動で確保して、もとのオブジェクトのメモリ領域の内容を新しいメモリ領域にコピーする必要があります。
class MyClass {
public:
int *data;
int size;
// 自定义的拷贝构造函数
MyClass(const MyClass& other) {
size = other.size;
data = new int[size];
std::copy(other.data, other.data + size, data);
}
// 自定义的赋值运算符
MyClass& operator=(const MyClass& other) {
if (this != &other) {
size = other.size;
delete[] data;
data = new int[size];
std::copy(other.data, other.data + size, data);
}
return *this;
}
// 析构函数
~MyClass() {
delete[] data;
}
};
- スマートポインタの使用:C++11では、動的メモリの管理を手動で行う必要がなくなるスマートポインタ(std::shared_ptr、std::unique_ptrなど)が導入されました。
class MyClass {
public:
std::shared_ptr<int> data;
int size;
// 自定义的拷贝构造函数
MyClass(const MyClass& other) {
size = other.size;
data = std::make_shared<int[]>(size);
std::copy(other.data.get(), other.data.get() + size, data.get());
}
// 自定义的赋值运算符
MyClass& operator=(const MyClass& other) {
if