【C++】static constなメンバの初期化

結構わかりにくい感あります.メモ代わりに記事に.

こんな感じで初期化します.

// ----------------------------------------
// .hファイルに書く内容
#include <stdio.h>

class Output
{
public:
    // コンストラクタ.
    Output(int Val) : Num(Val){}
    // 出力関数.constを付けないとコンパイルエラーになる.
    void Print() const{ printf("%d", Num); }
private:
    int Num;
};

class OutData
{
public:
    // static constなメンバ.
   static const Output Dt;
};

// ----------------------------------------
// .cppファイルに書く内容

// ここで初期化する.
const Output OutData::Dt(5);

int main()
{
    // 予め初期化しておいたDtクラスのPrint関数を呼び出す.
    OutData::Dt.Print();
    return 0;
}

結果は以下のように出力されます.

5

さて,肝心の初期化部分ですが,以下のコードを.cppファイルに書きます.
SampleClassとStaticConstMember::Valueは必要に応じて読み替えて下さい.

// class SampleClass{ ... };
// class StaticConstMember
// {
// public:
//     static const SampleClass Value;
//     ...
// };
// と宣言されていたとして
const SampleClass StaticConstMember::Value(/*この中に初期化に必要な引数を入れる*/);

ちなみに,static const intの場合は以下のようにも書けます.

class ConstValue
{
public:
    // static const intなメンバ.=で初期化できる.
   static const int Boy = 0;
   static const int Girl = 5;
};

ここで注意する必要があることは,この方法で初期化したクラスはconstなので,そこから呼び出すクラスの関数にはconstが付いている必要があります(値を書き換えることができたら意味が無いのでこれは当然とも言えますが).
具体的には以下のような感じです.

class Output
{
public:
    // これはOK.
    void PrintA() const{ printf("A"); }
    // これは無理.
    //void PrintB(){ printf("B"); }
};

もし,ユーザーには見えない部分で値を書き換えて使いたいと思ったら,以下のようにすると動作します.ここで,constは省いてはいけません.

class Output
{
public:
    // これはOK.
    void ChangeVal(double Num) const{ OutputNum = Num; }
    // これは無理.
    //void ChangeVal(double Num){ OutputNum = Num; }
private:
    // mutableを付ける.
    mutable double OutputNum;
};