C++編 目次

 コンストラクタ
  /デストラクタ

 


・メンバイニシャライザでの初期化順序

・オブジェクトを作った後に初期化する
・明示的なブロック化

 演算子

 

・代入演算子のオーバーロード

 文字列操作

 

・stringの多重連結を使用した代入

 

 


トップページへ戻る

オブジェクトを作った後に初期化する

 次のような、日時を保持する単純なクラスを考えてみます。このクラスはコンストラクタでメンバを初期化します。オブジェクトを作った後でメンバを更新する関数は用意されていません。

// 日時クラス
class CDateTime
{
public:
    CDateTime(){}
    CDateTime(int year, int month, int date, int hour, int min, int sec) :
        m_year(year), m_month(month), m_date(date), 
        m_hour(hour), m_min(min), m_sec(sec){}
    virtual ~CDateTime(){}
    
    int     GetYear(){return m_year;}
    int     GetMonth(){return m_month;}
    int     GetDate(){return m_date;}
    int     GetHour(){return m_hour;}
    int     GetMin(){return m_min;}
    int     GetSec(){return m_sec;}

private:
    int     m_year;
    int     m_month;
    int     m_date;
    int     m_hour;
    int     m_min;
    int     m_sec;
};

 このようなクラスでは、次のような方法でメンバの更新をすることができます。

#include "CDateTime.h"

int main(int argc, char *argv[])
{
    CDateTime   dt1(2006, 10, 17, 20, 0, 0);    // (1)コンストラクタでの初期化
    CDateTime   dt2, dt3;                       // (2)コンストラクタで初期化しない
    
    dt2 = dt1;                                  // (3)別オブジェクトからのコピー(代入)
    dt3 = CDateTime(2006, 10, 18, 6, 0, 0);     // (4)一時オブジェクトからのコピー(代入)
    
    return 0;
}

 (1)は通常の使い方で、コンストラクタでメンバの初期化をしています。(2)はコンストラクタでは初期化していません。

 このように、コンストラクタで初期化しないで、オブジェクトを作った後でメンバを更新したいときは、(3)のように他の初期化済みのオブジェクトを代入する方法があります。この方法では、別オブジェクトの内容がそのままビットコピーされます。

 この方法では、コピー元である別オブジェクトを用意しないといけません。また、クラスの代入では、メンバがすべてそのままコピーされます。このことによって問題が起こることがあります。

 それは、動的に確保したメモリのポインタなどをメンバに持っていて、デストラクタでメモリを開放するような場合です。この場合はコピー元のオブジェクトとコピー先のオブジェクトが同じメモリアドレスのポインタを持つことになるので、2重に開放処理が実行されてしまいます

 これを避けたい場合は、代入演算子のオーバーロードをして、代入時のメモリの扱いを適切に処理する必要があります。

 また、(4)のように一時オブジェクトを作ってから、そのオブジェクトの内容をコピー(代入)する方法があります。この場合は、別オブジェクトを用意する必要はありません。この場合気をつけることは、代入が実行された後に、一時オブジェクトのデストラクタが呼び出されるということです。

 この場合も、動的メモリのポインタをメンバに持っている場合は、一時オブジェクトのデストラクタですでに開放されてしまうので、代入先のオブジェクトではそのメモリは使えなくなります。

 この場合も代入演算子をオーバーロードして、代入時に動的メモリとその内容を複製するなどの処理をする必要があります。

 今回の例は、動的メモリを使わない単純なクラスなので、他オブジェクトからのコピーでも、一時オブジェクトからのコピーでも問題はありません。

 管理人は結構この"一時オブジェクト"を積極的に使います。(便利なので)