C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++のコピーコンストラクタとは?仕組みと実装方法をサンプルコード付きで解説

コピーコンストラクタは、コンストラクタの一種です。同じクラスのオブジェクトを受け取り、その値を使って新しいオブジェクトを生成・初期化します。もしクラス内でコピーコンストラクタが定義されていない場合、コンパイラが自動的にデフォルトのコピーコンストラクタを生成します。

ただし、ポインタ変数や動的メモリ確保(new/delete)を持つクラスでは、デフォルトのコピーは浅いコピー(shallow copy)となり、同じメモリ領域を複数のオブジェクトが参照してしまう問題が発生します。そのため、このようなクラスでは独自のコピーコンストラクタを定義することが必須となります。

コピーコンストラクタのサンプルプログラム

以下に、コピーコンストラクタの動作を示すサンプルプログラムを紹介します。

#include<iostream>
using namespace std;
class Demo {
    private:
    int num1, num2;
    public:
    Demo(int n1, int n2) {
        num1 = n1;
        num2 = n2;
    }
    Demo(const Demo &n) {
        num1 = n.num1;
        num2 = n.num2;
    }
    void display() {
        cout<<"num1 = "<< num1 <<endl;
        cout<<"num2 = "<< num2 <<endl;
    }
};
int main() {
    Demo obj1(10, 20);
    Demo obj2 = obj1;
    obj1.display();
    obj2.display();
    return 0;
}

実行結果

num1 = 10
num2 = 20

num1 = 10
num2 = 20

プログラムの解説

上記のプログラムでは、Demoクラスに通常の引数付きコンストラクタとコピーコンストラクタの両方を定義しています。さらに、num1とnum2の値を出力するdisplay()関数も用意しています。

class Demo {
    private:
    int num1, num2;
    public:
    Demo(int n1, int n2) {
        num1 = n1;
        num2 = n2;
    }
    Demo(const Demo &n) {
        num1 = n.num1;
        num2 = n.num2;
    }
    void display() {
        cout<<"num1 = "<< num1 <<endl;
        cout<<"num2 = "<< num2 <<endl;
    }
};

ポイントとなるのは、コピーコンストラクタの宣言部分です。引数としてconst Demo &nのように、同じクラスへのconst参照を受け取ります。参照渡しにすることで無駄なコピーを防ぎ、constを付けることで元のオブジェクトが変更されないことを保証しています。

main関数での処理の流れ

main()関数では、まずobj1を引数付きコンストラクタで初期化し、次にobj2を「Demo obj2 = obj1;」という形式でコピーコンストラクタを使って初期化しています。このとき、obj1の値がobj2へコピーされます。最後に、両方のオブジェクトの値を表示しています。

Demo obj1(10, 20);
Demo obj2 = obj1;
obj1.display();
obj2.display();

実行結果からわかるように、obj2にはobj1と同じ値(num1 = 10、num2 = 20)が正しくコピーされていることが確認できます。

まとめ

コピーコンストラクタは、オブジェクトの複製を作る際に呼び出される特別なコンストラクタです。単純なクラスではコンパイラが自動生成したものでも十分ですが、ポインタや動的メモリを扱うクラスでは深いコピー(deep copy)を行う独自のコピーコンストラクタを定義することで、二重解放などのバグを防ぐことができます。

  1. C++のデストラクタとは?基本構文と使い方を実例で解説

    デストラクタ(Destructor)は、C++のクラスに属する特別なメンバ関数の一つで、オブジェクトを破棄する役割を担います。関数の終了やプログラムの終了、deleteによる明示的な削除など、オブジェクトがスコープ外に出るタイミングで自動的に呼び出されます。 デストラクタは通常のメンバ関数とは異なり、引数を受け取らず、戻り値も返しません。また、クラス名と同じ名前を持ち、その先頭にはチルダ(~)を付けるのが決まりです。なお、デストラクタはオーバーロードできないため、1つのクラスに定義できるのは1つだけという点にも注意しましょう。 以下に、C++におけるデストラクタの動作を確認できるサンプルプログ

  2. C++のコンストラクタとは?デフォルトコンストラクタと引数付きコンストラクタの使い方を解説

    C++のコンストラクタとはコンストラクタ(constructor)とは、クラスの新しいオブジェクトが生成される瞬間に自動的に呼び出される特別なメンバ関数です。コンストラクタには以下のような特徴があります。関数名がクラス名と同じである戻り値の型を持たない(voidも指定しない)オブジェクト生成時に自動的に実行されるコンストラクタの主な役割は、クラスのメンバ変数に初期値を与えることです。これにより、オブジェクトは生成された時点で適切な状態を持つことが保証されます。C++のコンストラクタには、主に「デフォルトコンストラクタ」と「引数付きコンストラクタ(パラメータ化コンストラクタ)」の2種類があります