C++ 静的メンバ変数 静的メンバ関数 static 書いて覚えるための初心者自己中記事
static を使った静的ローカル変数は、
関数を抜けても値が保持される
初期化は一度きり
だった。
クラスのメンバ変数にstatic をつけると
静的メンバ変数になる。
静的メンバ変数は実体がなくなる。(?)(コンパイル時にリンクエラーになる。)
なので別に実体を作る必要が出てくる。
実体をつくるにはメンバ関数の実装の感覚で行う。
class.h
class Integer { public: Integer(int num = 0); void Show(); private: static int m_value; };
class.cpp
Integer::Integer(int num) { m_value = num; } void Integer::Show() { std::cout << m_value << std::endl; } int Integer::m_value; //staticメンバ変数の実体
source.cpp
int main() { Integer a(100), b(300); a.Show(); b.Show(); system("pause"); }
//output
300
300
結果、Integerクラスのオブジェクト a b の結果はどちらも300
静的メンバ変数は実態を一つしか持たないため、オブジェクトを複数作っても実態は一つ。
そして最後に初期化された値を持つことになる。
また、デフォルト引数には静的なデータしか使えないが、このメンバ変数は静的メンバ変数なので使用できる。
静的メンバ変数は派生したとしても実態は一つ。
すべてのオブジェクトで共有できる。
静的変数はプログラムの初めに0で初期化される。
クラステンプレートの静的メンバ変数
関数テンプレートの静的ローカル変数
などは、テンプレート引数ごとに実態が作られた数だけ静的変数も実態を作られる。
静的メンバ変数はプログラムの初めに初期化されるので、
所属するクラスのオブジェクトが一つもなくても実体がある。
同じようにメンバ関数を静的にすると、オブジェクトがなくても呼び出すことが可能。
クラス名 :: 静的メンバ関数();
で呼び出せる。
class.h
class Integer { public: Integer(); ~Integer(); static void Show(); private: static int m_value; };
class.cpp
Integer::Integer() { ++m_value; } Integer::~Integer() { --m_value; } void Integer::Show() { std::cout << m_value << std::endl; } int Integer::m_value;
source.cpp
int main() { Integer::Show(); Integer a; a.Show(); { Integer b; a.Show(); } Integer c; Integer::Show(); system("pause"); }
//output
0
1
2
2
呼び出せた。
ただしこのやり方では静的メンバ関数は静的メンバ変数しか扱えない。
void Integer::Show(Integer& test) { std::cout << "m_value : " << m_value << std::endl; test.Test(); std::cout << "m_test : " << test.m_test << std::endl; }
こんな風に実態を渡せばOK。
静的メンバ定数の場合。
static int num; (静的メンバ変数)
static const int num = 100; (静的メンバ定数)
静的メンバ定数は静的メンバ変数と違って実体を作る作業をしなくても宣言時に初期化できる。これによって同クラス内の配列変数の要素数に使用できる。
ここまで。