3-1-4. コピーコンストラクタ

公開日: 9:56 3. オブジェクト指向編/3-1. クラスとオブジェクト/3-1-4. コピーコンストラクタ

コピーコンストラクタは前に生成された同じクラスのオブジェクトで初期化されたオブジェクトを生成するコンストラクタです。コピーコンストラクタは次のように使われます。

  • 同じ型の別のオブジェクトからオブジェクトを初期化
  • 関数への引数として渡すためにオブジェクトをコピー
  • 関数からの戻り値としてオブジェクトをコピー

コピーコンストラクタがクラスで定義されていなければ、コンパイラ自身が定義します。クラスがポインタ変数を持っていて動的なメモリ確保をしていれば、コピーコンストラクタが必要となります。コピーコンストラクタの一般的な形式は次のようになります。
classname (const classname &obj) {
   // コンストラクタの中身
}
objはオブジェクトへの参照であり、別のオブジェクトを初期化するのに使われます。

#include <iostream>

using namespace std;

class Line
{
   public:
      int getLength( void );
      Line( int len );             // コンストラクタ
      Line( const Line &obj );  // コピーコンストラクタ
      ~Line();                     // デストラクタ

   private:
      int *ptr;
};

// コンストラクタを含むメンバ関数の定義
Line::Line(int len)
{
    cout << "ノーマルコンストラクタがメモリ確保" << endl;
    // ポインタにメモリを割り当て
    ptr = new int;
    *ptr = len;
}

Line::Line(const Line &obj)
{
    cout << "コピーコンストラクタがメモリ確保" << endl;
    ptr = new int;
   *ptr = *obj.ptr; // copy the value
}

Line::~Line(void)
{
    cout << "メモリを開放!" << endl;
    delete ptr;
}
int Line::getLength( void )
{
    return *ptr;
}

void display(Line obj)
{
   cout << "線の長さ : " << obj.getLength() <<endl;
}

// プログラムの開始
int main( )
{
   Line line(10);

   display(line);

   return 0;
}
上のコードをコンパイルし実行すると、次の結果が得られます。
ノーマルコンストラクタがメモリ確保
コピーコンストラクタがメモリ確保
線の長さ : 10
メモリを開放!
メモリを開放!

少し手を加えてみます。

#include <iostream>

using namespace std;

class Line
{
   public:
      int getLength( void );
      Line( int len );             // コンストラクタ
      Line( const Line &obj );  // コピーコンストラクタ
      ~Line();                     // デストラクタ

   private:
      int *ptr;
};

// コンストラクタを含むメンバ関数の定義
Line::Line(int len)
{
    cout << "ノーマルコンストラクタがメモリ確保" << endl;
    // ポインタにメモリを割り当て
    ptr = new int;
    *ptr = len;
}

Line::Line(const Line &obj)
{
    cout << "コピーコンストラクタがメモリ確保" << endl;
    ptr = new int;
   *ptr = *obj.ptr; // 値のコピー
}

Line::~Line(void)
{
    cout << "メモリを開放!" << endl;
    delete ptr;
}
int Line::getLength( void )
{
    return *ptr;
}

void display(Line obj)
{
   cout << "線の長さ : " << obj.getLength() <<endl;
}

// プログラムの開始
int main( )
{
   Line line1(10);

   Line line2 = line1; // これもコピーコンストラクタが呼ばれる

   display(line1);
   display(line2);

   return 0;
}
上のコードをコンパイルし実行すると、次の結果が得られます。
ノーマルコンストラクタがメモリ確保
コピーコンストラクタがメモリ確保
コピーコンストラクタがメモリ確保
線の長さ : 10
メモリを開放!
コピーコンストラクタがメモリ確保
線の長さ : 10
メモリを開放!
メモリを開放!
メモリを開放!
  • ?±??G???g???[?d????u?b?N?}?[?N???A

0 件のコメント :

コメントを投稿