第28章 静かなるメンバ

 今回は新しいクラスを作ります。が、特に意味のないクラスです。ちょっと説明的になってしまいますが、勘弁して下さい(汗)。

 なお、数章後にまた CIntArray を改造するので、ソースは残しておくことをおすすめします。


 では、今回の要点です。


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


 今回はメンバ変数に static を付けてみます。これがどんな意味を持つか、それを確認していきたいと思います。

 今回使うクラスはこんな感じです。

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

class CNum
{
private:
    int m_num;

public:
    CNum(int num){ m_num = num; }
    void Disp()  { cout << m_num << endl; }
};

int main()
{
    CNum a(100), b(300);
    a.Disp();  b.Disp();
    return 0;
}
実行結果
100
300

 数値を保持してそれを表示するだけのクラスです。それ以上の意味はありません(汗)。このクラスがどうなっているかが分からない人は、もう一度講座を初めから読み直すことをおすすめします。

 では、早速 m_num の型に static を付けてみましょう。

リンクエラー
Num1.obj : 外部シンボル "CNum::m_num" は未解決です

 あらら、リンクエラーが出てしまいました。コンパイルは通ったみたいですが、リンクは通らなかったみたいです。

 このエラーは「実体がないよ」というエラーです。つまり、メンバ変数に static をつけると別に実体を作る必要があるということです。

 それはこのようにします。

class CNum
{
private:
    static int m_num;

public:
    CNum(int num){ m_num = num; }
    void Disp()  { cout << m_num << endl; }
};

int CNum::m_num;

 メンバ関数を実装するときと同じような感じですね。

<型> <クラス名>::<変数名>;

とし、こちらには static はつけません

 ファイルを分割するときは、これは cpp ファイルの方に書きます。ヘッダファイルに書くと二重定義を引き起こします。

 このようにすれば、メンバ変数に static を付けることができます。


 では、メンバ変数に static を付けるとどうなるのでしょう? 実際にプログラムを実行してみましょう。

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

class CNum
{
private:
    static int m_num;

public:
    CNum(int num){ m_num = num; }
    void Disp()  { cout << m_num << endl; }
};

int CNum::m_num;

int main()
{
    CNum a(100), b(300);
    a.Disp();  b.Disp();
    return 0;
}
実行結果
300
300

 a は 100 で初期化したにもかかわらず、両方とも 300 と表示されてしまいました。つまり、後に初期化した方の値が表示されたことになります。

 ある程度予想できると思いますが、このようになるのは static を付けたメンバ変数は実体が1つしかないからです。実体は int CNum::m_num; のところで定義された1つしかありません。これは何個 CNum のインスタンスを作っても言えることです

 ということで、a で m_num を 100 と初期化するも b のコンストラクタで 300 と上書きされ、a でも b でも 300 としか表示されなかったわけです。


 このようなメンバ変数を静的メンバ変数と呼びます。


 よくよく考えてみると、このプログラムは次のように書き換えることができます。

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

int g_num;

class CNum
{
public:
    CNum(int num){ g_num = num; }
    void Disp()  { cout << g_num << endl; }
};

int main()
{
    CNum a(100), b(300);
    a.Disp();  b.Disp();
    return 0;
}
実行結果
300
300

 しかし、データのアクセス制限もできませんし、CNum と関係のある変数という意味合いも薄れます。インラインで利用しようとすると必然的にグローバル変数にする必要もあります。静的メンバにした方が安全で分かりやすいことがわかります。


 それでは、今回の要点です。


 次回も静的メンバ変数をやりたいと思います。それでは。


第27章 暗黙の了解 | 第29章 静かなるメンバ2

Last update was done on 2000.10.21

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