ホームに戻る
 コピーコンストラクタ、コピー代入演算子

#include <iostream>

/*
*
*   コピーコンストラクタ
*
*   コピーコンストラクタは初期化時に、
*   クラスのメンバ値をコピーするときに、
*   自動的に呼び出されるコンストラクタのことです。
*
*   メンバ変数のコピーの際に起こる最大の問題は、
*   メンバ値にポインタがあった場合に、
*   アドレス値をコピーしても実体をコピーしない問題です。
*   コピーコンストラクタでこの問題を解決できます。
*
*   インスタンス作成時に用いることができるのは当然ですが、
*   関数の引数にクラスを渡す際にも、
*   コピーコンストラクタが呼ばれるので重要です。
*
*   メンバ変数にポインタがある場合には、
*   かならずコピーコンストラクタの対応が必要です。
*
*   また、コピーコンストラクタはコピー代入演算子と似ています。
*   見分け方はコピーコンストラクタは必ず初期化時に呼ばれることです。
*
*/

class A{
  enum{p_num = 2};
  int *p;
  A& operator=(const A &other){  // コピー代入演算子
    if(this == &other)return *this;

    num = other.num;

    p = new int[p_num];

    for(i = 0; i < p_num; i++){
     p[i] = other.p[i];
    }

    return *this;
  }
public:
  int num;
  A(){num = 3; p = new int[p_num];}
  A(const A &other);  // コピーコンストラクタ
  ~A(){delete [] p;}
  void setNum(int index, int num){p[index] = num;}
  int getNum(int index){return p[index];}
};

A::A(const A &other){
  int i;

  num = other.num;

  p = new int[p_num];

  for(i = 0; i < p_num; i++){
   p[i] = other.p[i];
  }

  std::cout << "copy const A" << std::endl;
}

using namespace std;

void f(A a3){  // コピーコンストラクタを呼ぶ
  cout << a3.getNum(0) << endl;
  cout << a3.getNum(1) << endl;
  cout << a3.num << endl;
}

int main(){
  A a1;

  a1.setNum(0, 1);
  a1.setNum(1, 2);

  A a2 = a1;  // コピーコンストラクタを呼ぶ
  //a2 = a1;  これはただの代入でコピーコンストラクタを呼ばない

  cout << a2.getNum(0) << endl;
  cout << a2.getNum(1) << endl;
  cout << a2.num << endl;

  f(a2);

  return 0;
}

 結果

copy const A
1
2
3
copy const A
1
2
3

inserted by FC2 system