コピーコンストラクタ

スポンサーリンク
スポンサーリンク
ライフスタイル関連のコンテンツ
お金 | 仕事 | 勉強 | プライベート | 健康 |
プログラミング関連のコンテンツ
C言語/C++入門 | Ruby入門 | Python入門 | プログラミング全般

コピーコンストラクタとは、クラスをまるごとコピーする特別なコンストラクタのことです。
コピーコンストラクタの宣言の仕方は、以下のようになります。

スポンサーリンク

class <クラス名>
{
public:
    <クラス名>(const <クラス名>& <クラス自身のインスタンス>);  // コピーコンストラクタ
};

まず、コピーコンストラクタの名前は、通常のコンストラクタと同様に、クラス名を名前にします。
通常のコンストラクタとの区別は、引数が違うところです。
コピーコンストラクタの引数は、クラス自身のインスタンスを参照渡しで指定し、さらにconstをつけます。

const <クラス名>& <クラス自身のインスタンス>

という引数になります。
クラスは、自分で定義できる、抽象化されたデータ型の一つであることに注意です。
参考:クラス(コンピュータ)

実際のコピーコンストラクタの処理を実装する定義は、通常のコンストラクタと同様に行います。

<クラス名>::<クラス名>(const <クラス名>& <クラス自身のインスタンス>) {
    処理・・・;
}

コピーコンストラクタを定義して、動作確認をしてみる。

/***********************************
Stack
 整数型のスタックを実装する
***********************************/
 
#include <assert.h>
#include <cstdlib>
#include <iostream>
 
const int STACK_SIZE = 100;    // スタックの最大サイズ
 
/***********************************
stackクラス
 整数型のスタックを実装するクラス
 
メンバ関数(メソッド)
 init    :スタック初期化
 push    :スタックに要素プッシュ
 pop     :スタックから要素ポップ
***********************************/
 
class stack {
    public:
        int count;               // スタック内の要素の数
        int data[STACK_SIZE];    // 要素
    public:
        // コンストラクタ
        stack();    // voidがないことに注意
        // コピーコンストラクタ
        stack(const stack& obj);
        // スタックに要素をプッシュ
        void push(const int item);
        // スタックから要素をポップ
        int pop();
};
 
/***********************************
stack::stack
 スタックの初期化コンストラクタ
************************************/
 
inline stack::stack() {
    count = 0;    // スタックの要素数を0に設定
}
 
/***********************************
stack::stack(const stack& obj)
 スタックの初期化コピーコンストラクタ
 スタックのデータ(count,data[STACK_SIZE])
 をコピーする。
************************************/
 
inline stack::stack(const stack& obj) {
    int i;    // データコピーのためのインデックス
 
    for (i = 0; i < obj.count; ++i) {
        data[i] = obj.data[i];
    }
    count = obj.count;
}
 
/***********************************
stack::push
 プッシュ演算。
 スタックの最後に要素を追加して、
 要素数をインクリメントする。
 
引数
 item        :追加する要素の値
 
戻り値        :なし
************************************/
 
inline void stack::push(const int item) {
    assert((count >= 0) &&
        (count <= static_cast<int>(sizeof(data)/sizeof(data[0]))));
    
    data[count] = item;
    ++count;
}
 
/***********************************
stack_pop
 ポップ演算。
 スタックの先頭要素を取り出して、
 要素数をデクリメントする。
 
戻り値        :スタックの最後の値
************************************/
 
inline int stack::pop() {
    // スタックの要素数をデクリメント
    --count;
 
    assert((count >= 0) &&
        (count < static_cast<int>(sizeof(data)/sizeof(data[0]))));
    
    // 最後の値を返す
    return (data[count]);
}
 
// スタックをテストするためのルーチン
int main() {
    // stackを使用可能にする
    stack a_stack;    // stack構造体の宣言。classは省略可。
 
    // 要素をスタックにプッシュ
    a_stack.push(1);
    a_stack.push(2);
    a_stack.push(3);
 
    // コピーコンストラクタでスタックのコピーを作成
    stack b_stack(a_stack);
 
    // コピーされたスタックから要素をポップ
    std::cout << "b_stack:\n";
    std::cout << b_stack.pop() << "\n";
    std::cout << b_stack.pop() << "\n";
    std::cout << b_stack.pop() << "\n";
 
    // 元のスタックから要素をポップ
    std::cout << "a_stack:\n";
    std::cout << a_stack.pop() << "\n";
    std::cout << a_stack.pop() << "\n";
    std::cout << a_stack.pop() << "\n";
 
    return 0;
}

実行結果。

b_stack:
3
2
1
a_stack:
3
2
1

コピーコンストラクタにより、コピーが行われたことを確認できました。

コピーコンストラクタの理解はなかなか難しいので復習をする。
以下、後学のための資料ページ。

参考:
C++編(言語解説) 第16章 コピーコンストラクタ

スポンサーリンク
 
スポンサーリンク