「C++の基礎 - クラス」の版間の差分

ナビゲーションに移動 検索に移動
57行目: 57行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
非staticのメンバ変数が、オブジェクト1つごとに別個に存在することに対して、staticメンバ変数は、クラスに対して1つだけ存在する。<br>
オブジェクトが複数存在しても、各オブジェクトからただ1つの変数を共有する。<br>
<br>
<u>このような特徴を持つため、staticメンバ変数は、各オブジェクトが必要とする共通情報を管理することに利用できる。</u><br>
<br>
以下の例では、インスタンス化したオブジェクトの総数を管理している。<br>
<syntaxhighlight lang="c++">
// CSampleClass.h
#ifndef CSAMPLECLASS_H
#define CSAMPLECLASS_H
class MyClass
{
public:
    CSampleClass();
    ~CSampleClass();
private:
    static int msObjectCount;  // staticメンバ変数の宣言
};
#endif
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
// CSampleClass.cpp
#include "CSampleClass.h"
// staticメンバ変数の実体
int MyClass::msObjectCount;
CSampleClass::CSampleClass()
{
    msObjectCount++;
}
CSampleClass::~CSampleClass()
{
    msObjectCount--;
}
</syntaxhighlight>
<br>
クラスの外部から、staticメンバ変数にアクセスする場合は、<code>クラス名::staticメンバ変数名</code>という形で、スコープ解決演算子を使用して記述する。<br>
また、一般的ではないが、非staticなメンバ変数と同様に、<code><オブジェクト名>.<staticメンバ変数名></code>のようなアクセスも可能である。<br>
<br>
<u>一般的には、staticメンバ変数は非公開である方がよいが、<code>const static</code>を付加している場合は、公開しても問題ない。</u><br>
<br>
クラスの定義内やメンバ関数の定義内から、自身のクラスのstaticメンバ変数へアクセスする場合は、staticメンバ変数名のみを使用して記述することができる。<br>
<br>
==== staticメンバ関数 ====
クラスのメンバ関数にも<code>static</code>指定子を付加することができる。(staticメンバ関数)<br>
<syntaxhighlight lang="c++">
class <クラス名>
{
    static <戻り値の型> <メンバ関数名>(<引数>);
};
<戻り値の型> <クラス名>::<メンバ関数名>(<引数>)
{
    // ...略
}
</syntaxhighlight>
<br>
staticメンバ関数に<code>const</code>を付加することはできない。<br>
また、staticメンバ関数をインライン関数にすることも可能である。<br>
<br>
staticメンバ関数のオーバーロードも可能であるが、staticメンバ関数と非staticメンバ関数との間において、同じ名前を使用することはできない。<br>
<br>
staticメンバ変数と同様に、staticメンバ関数もクラスに属するため、staticメンバ関数はオブジェクトを生成せずに呼び出すことができる。<br>
<クラス名>::<メンバ関数名>(<引数>)
<br>
<u>オブジェクト(実体)から呼び出さないため、staticメンバ関数内では、<code>this</code>ポインタを使用することはできない。</u><br>
また、一般的ではないが、<code><オブジェクト名>.<staticメンバ関数名>(<引数>)</code>の形で呼び出すことも可能である。<br>
<br>
非staticなメンバ関数から、staticメンバ関数を呼び出すことはできるが、<u>staticメンバ関数から、非staticのメンバ変数にアクセスできない。</u><br>
<br>
<code>public</code>なstaticメンバ関数は、通常の関数と同様に扱うことができるが、<br>
クラスに含まれていることにより、スコープを限定できること、staticメンバ変数という専用のデータの置き場が使用できることが特徴である。<br>
<br>
<syntaxhighlight lang="c++">
#ifndef CSAMPLECLASS_H
#define CSAMPLECLASS_H
class CSampleClass
{
public:
    CSampleClass()
    {
      msObjectCount++;
    }
    ~CSampleClass()
    {
      msObjectCount--;
    }
    static int GetObjectCount()
    {
      return msObjectCount;
    }
private:
    static int msObjectCount;  // staticメンバ変数の宣言
};
// staticメンバ変数の実体
int CSampleClass::msObjectCount = 0;
#endif
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
// main.cpp
#include <iostream>
#include "CSampleClass.h"
int main()
{
    std::cout << CSampleClass::GetObjectCount() << std::endl;  // msObjectCount : 0
    CSampleClass  c1;
    CSampleClass *c2 = new CSampleClass();
    std::cout << CSampleClass::GetObjectCount() << std::endl;  // msObjectCount : 2
    delete c2;
    std::cout << CSampleClass::GetObjectCount() << std::endl;  // msObjectCount : 1
}
</syntaxhighlight>
<br><br>
<br><br>


案内メニュー