コンテンツにスキップ

ディープコピーとシャローコピー

ディープコピー

C++ のコピーは基本的にはディープコピーと呼ばれるものです。

ディープコピーは実体ごとコピーされるため、コピーした分のメモリ領域の確保が必要になります。 ディープコピーの場合、コピー先(or コピー元)のオブジェクトを編集しても、他方のオブジェクトには影響を及ぼしません。

int x = 100;
int y = x; // x を y へディープコピー(図1)
y = 50; // y を 50 に書き換える(図2)
std::cout << x << std::endl; // x は100のまま

図1

図1

図2

図1

シャローコピー

ポインタをコピーする場合はシャローコピーになります。

シャローコピーではポインタの向き先だけがコピーされ、実体はコピー元の領域のままなので、 ディープコピーのようなコピーした分のメモリの確保は起きません。

参照の場合も、ポインタと同様にシャローコピーになります。

int* x = new int(100);
int* y = x; // x を y へシャローコピー(図3)
*y = 50; // y が指す先の値を 50 に書き換える(図4)
std::cout << *x << std::endl; // x が指す先の値も 50 になる

図3

図3

図4

図4

関数の引数

ディープコピーとシャローコピーは関数の引数でも区別されます。

#include <iostream>

void ChangeToFifty1(int v) {  // ディープコピー
    v = 50;
}

void ChangeToFifty2(int* v) {  // シャローコピー
    *v = 50;
}

int main() {
    int a = 100;
    ChangeToFifty1(a);
    std::cout << a << std::endl;  // 100

    int b = 100;
    ChangeToFifty2(&b);
    std::cout << b << std::endl;  // 50

    return 0;
}