#pragma twice

KAB-studio > プログラミング > #pragma twice > 218 Version 11.18 コンストラクタって複雑!

#pragma twice 218 Version 11.18 コンストラクタって複雑!

前のページへ 表紙・目次へ 次のページへ

 Version 11.18
コンストラクタって複雑!

なんかのっけから嫌なタイトルね……
コンストラクタはかなり複雑な面があるから
用心してかかれってことね
そういうこと。コンストラクタの基本は、前回の CHasConstructor 
クラス名と同じで、戻り値なし、だね
そうそう。あと、 Version 7.08 ( No.128 ) も読んでおいて
これは使う時のだね
それをふまえた上で、まずは引数を持つコンストラクタについて

// 引数付きコンストラクタを持つクラス
class CHasParamConstructor
{
private:
    int m_iData;

public:
    // 引数付きコンストラクタ。
    CHasParamConstructor( int p_i )
    {
        m_iData = p_i;
        TRACE( "%d\n", m_iData );
    }
};

// 使用例。
void Use_CHasParamConstructor()
{
    CHasParamConstructor cHasParamConstructor( 100 );
    // 100
}

なるほど、コンストラクタも普通の関数みたいに引数付けられるんだね。
でも、変数作るときに後ろに()付けるのってなんか変……
ふふふふふ
な、なに?

void Use_intParam()
{
    int i( 200 );
    TRACE( "%d\n", i );
    // 200
}

うわ、気持ち悪ッ!!
というように、普通の型でも同じように初期化できるんです
って、 int にもコンストラクタがあるってこと??
ないよ。でも、あるみたいに使える、そういう仕様になってるってこと
クラスにできることは、普通の型にもできるってことね……でもヤダ
なーこれ。普通は

void Use_intParamEqual()
{
    int i = 200;
    TRACE( "%d\n", i );
    // 200
}

って感じだよね。! もしかして……

void Use_CHasParamConstructorEqual()
{
    CHasParamConstructor cHasParamConstructor = 100;
    // 100
}

うわできちゃったよ……
そう、普通の型にできることはクラスでもできるってこと
なんか妙ねー
でも

    CString cStr = "あいうえお";

あ、これはわかりやすいかも
でしょう。まぁでも、クラスで = が使えるのは、引数がひとつのコンス
トラクタだけ。たとえば

// 引数ふたつ付きコンストラクタを持つクラス
class CHas2ParamConstructor
{
private:
    int m_iData;

public:
    // 引数ふたつ付きコンストラクタ。
    CHas2ParamConstructor( int p_i, int p_i2 )
    {
        m_iData = p_i + p_i2;
        TRACE( "%d\n", m_iData );
    }
};

みたいに引数がふたつ付いてるコンストラクタの場合

void Use_CHas2ParamConstructor_Bad()
{
    CHas2ParamConstructor cHas2ParamConstructor = 100;
    // コンパイルエラー。
    // error C2440: 'initializing' : 'const int' から 
    // 'class B1::CHas2ParamConstructor' に変換することはできません。
    // (新しい動作 ; ヘルプを参照)
    // コンストラクタはソース型を持てません、またはコンストラクタの
    // オーバーロード レゾリューションがあいまいです。
}

あ、コンパイルエラー
こういう場合には

void Use_CHas2ParamConstructor()
{
    CHas2ParamConstructor cHas2ParamConstructor( 100, 200 );
    // 300
}

って、普通に関数みたく呼ばなきゃいけないわけねー
そういうこと。 = を使うことの呼びやすさと、書き方の統一を考える
と、どっちがいいとは一概には言えないかもね
書き方の統一?
引数がひとつなら = 、ふたつ以上なら () で、っていうのは変でしょ
そか、混ざっちゃうのはいけないんだね
そういうこと。だけど = って書いた方がわかりやすい場合もあるわけ

むむむ、じゃああたしはどっちにすればいいの?
それは自分で考えましょう

でも、他の人と共同でプログラムを組むときにはその辺はちゃんと決める
ようにね
どっちを使うにしろ、一緒にはしなきゃってことね
そゆこと。さて、次の話。今使ったクラスを、今度は引数を渡さないで
使ってみます

void Use_CHas2ParamConstructor_NoParam_Bad()
{
    CHas2ParamConstructor cHas2ParamConstructor;
    // コンパイルエラー。
    // error C2512: 'CHas2ParamConstructor' : 
    // クラス、構造体、共用体にデフォルト コンストラクタが
    // ありません。
}

げ、コンパイルエラーだ
クラスに引数付きコンストラクタがある場合には、その引数付きのしか呼
べないんです。だから、引数のないコンストラクタがないばあいには
エラーになっちゃう、と
この場合、方法はふたつ。ひとつは、引数のないコンストラクタを作るこ
と。さっきのクラスを

// 引数ふたつ付きコンストラクタを持つクラス
class CHas2ParamConstructor
{
private:
    int m_iData;

public:
    // 引数のないコンストラクタ。
    CHas2ParamConstructor()
    {
        m_iData = 0;
    }

    // 引数ふたつ付きコンストラクタ。
    CHas2ParamConstructor( int p_i, int p_i2 )
    {
        m_iData = p_i + p_i2;
        TRACE( "%d\n", m_iData );
    }
};

ってすれば
引数のないコンストラクタが呼ばれるから大丈夫ってことね
もうひとつの方法は、コンストラクタをひとつも作らないっていう方法
へ?
 Version 11.16 ( No.216 ) で CHasMember ってクラスを作ったでしょ
そういえば、あれにはコンストラクタがなかったけど使えたね
実は、コンストラクタがひとつもない場合には、自動的に引数なしのコン
ストラクタが作られるんです
へー、だからコンストラクタを作ったときと同じようになるんだ
そういうこと。この自動的に作られるのを【デフォルトコンストラクタ】
って言います
あ、それって Version 7.08 のでもやったね
そう、あれと同じ。ただ、行儀良くするなら、何もする必要がなくても、
引数なしのコンストラクタは作っておいた方がいいかな
デフォルトコンストラクタを使わないで、ってこと?
その方がわかりやすいからね。ちょっとめんどくさいけど
確かに
あと、わざと引数のないコンストラクタを作らない、っていう方法もある
からね
え? だってそしたら、普通に変数作れないじゃん
そういう場合が必要な時もあるってこと。たとえば今回紹介したクラスは 
int のメンバ変数を持ってるけど、このメンバ変数の初期値を決められない
場合とかは?
それってどういう場合?
たとえば曜日とか
曜日……確かに、初期値って言われると難しいね。日曜日とかそんな気も
するけど、なんか違う気もするし……
そういう場合には引数付きコンストラクタだけ作って、必ず初期値を渡し
てもらうようにすれば
問題ないわけね

/*
    Preview Next Story!
*/
こういうのって、なんとなくわかるけど、それ止まりってゆーか
えっと、じゃあこれから今のコード見ないで10回書いて
へ!?
っていうくらい、練習した方がいいよ
算数の書き取りドリルですかそれは
というわけで次回
< Version 11.19 オーバーロード関数を作ってみよう >
につづく!
僕もやったし
やったんかい!
いや、ツッコミ入れるとこじゃないんだけど……
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。