第39章 クラステンプレート3

 今回は静的メンバを持つクラステンプレートを作ってみたいと思います。例によって意味のないクラスになりますが、ご勘弁を...。


 では、今回の要点です。


 では、いってみましょう。


 さて、今回は静的メンバのお話です(第28章第29章第30章参照)。

 静的メンバとは「そのクラスと派生クラスの実体全体で共有されるメンバ」のことでした。より簡単に言うと、「グローバル変数とグローバル関数のようなものを、アクセス制限できる「クラス」というものの中に閉じこめた物」です。public にしてしまえば、ほとんどグローバル変数・関数と同じです。

 そして、静的メンバ変数はいくらクラスの実体を作っても1つの実体が共有されるのでした。静的メンバ変数はこの世に1つ。それがC++言語のルールです。(関数は静的でなくても1つですね。)


 ここで気になるのが、「クラステンプレートでは静的メンバ変数はどうなるのだろうか?」ということです。クラステンプレートをいくつも実体化させてもその全体で1つしかできないのか、それとも各テンプレートインスタンス(テンプレートの実体)毎に1つずつできるのか、気になるところです。

 こういうときはどうするのでしたか? そうです。確かめてみるのです。ということで次のプログラムを見て下さい。

プログラム
// SMember5.cpp
#include <iostream.h>

// たまには TYPE 以外の名前にしてみました
template <typename SOMETHING>
class CSomething
{
private:
    static int something;
public:
    static void Disp();
};

// テンプレートの静的メンバ変数も
// こんな感じで実体定義したのでいいのかな?
// とやってみます
template <typename SOMETHING>
int CSomething <SOMETHING> ::something = 0;

// something のアドレスの表示
template <typename SOMETHING>
void CSomething <SOMETHING> ::Disp()
{
    cout << "アドレス : " << &something << endl;
}

int main()
{
    // 実体が一度も使われませんという警告が出ますが
    // ここでは無視して構いません
    CSomething <int>   st1;
    CSomething <char>  st2;
    CSomething <void*> st3;
    CSomething <int>   st4;
    CSomething < CSomething <int> > st5;

    // 静的メンバ関数は
    // 別に実体を使って呼んでもいいのでしたね
    st1.Disp();
    st2.Disp();
    st3.Disp();
    st4.Disp();
    st5.Disp();

    return 0;
}
実行結果例
アドレス : 0x0042ED60
アドレス : 0x0042ED64
アドレス : 0x0042ED68
アドレス : 0x0042ED60
アドレス : 0x0042ED6C

 結果を見て分かるとおり、「各テンプレートインスタンス毎に1つずつできる」というのが正解のようですね。

 このように、クラステンプレートでは各テンプレートインスタンス毎に1つずつ別の静的メンバ変数が作られます

 そして、静的メンバ変数の実体を定義するときの文法は、メンバ関数の時と同じになります。


 よくよく考えてみれば、こういうことがあるのでこのことは当然なことです。

template <typename SOMETHING>
class CSomething
{
private:
    static SOMETHING something;
public:
    static const SOMETHING& Get();
};

template <typename SOMETHING>
SOMETHING CSomething <SOMETHING> ::something;

// something の参照の取得
template <typename SOMETHING>
const SOMETHING& CSomething <SOMETHING> ::Get()
{
    return something;
}

 静的メンバでテンプレート引数を利用しています。こういう状態で全部共有されてしまうとは考えられないことですね。このことを頭に入れておけば、どうなるか悩むことはなくなるでしょう。


 では、今回の要点です。


 次でテンプレートについては大体終わりになります。では、次回まで。


第38章 クラステンプレート2 | 第40章 シリアル入り

Last update was done on 2000.12.14

この講座の著作権はロベールが保有しています