概要
staticメンバ
staticメンバ変数
クラスのメンバ変数にstatic
を付加することにより、staticメンバ変数となる。
staticメンバ変数は、クラスの定義に記述しただけでは定義したことにならないため、実体となる定義をクラス定義と同じスコープに記述する必要がある。
class CSampleClass
{
static 型名 メンバ変数名; // 宣言
};
型名 CSampleClass::メンバ変数名; // 定義
staticメンバ変数は、オブジェクトを生成せずにプログラムの開始時に既に存在しているため、自動的にゼロで初期化される。
ただし、staticメンバ変数の型が、const
な整数型、または、const
なenum
型の場合に限り、宣言と同時に初期化子を与えることができる。
class CSampleClass
{
private:
enum E { e1, e2 };
static const int ci = 100; // OK
static const E ce = e1; // OK
static const double cf = 1.0; // コンパイルエラー
static int i = 100; // コンパイルエラー
static E e = e1; // コンパイルエラー
};
コンパイルエラーになるパターンでは、定義時に初期化子を与える必要がある。
class CSampleClass
{
private:
enum E
{
e1,
e2
};
static const int ci = 100; // OK
static const E ce = e1; // OK
static const double cf;
static int i;
static E e;
};
const double CSampleClass::cf = 1.0; // OK
int CSampleClass::i = 100; // OK
CSampleClass::E CSampleClass::e = CSampleClass::e1; // OK
staticオブジェクト
staticクラスは、自動的にゼロで初期化された後、staticクラスが宣言された箇所が初めて実行される時にコンストラクタが呼び出される。
staticで宣言したクラスの場合、任意の関数が終了してもデストラクタは呼び出されない。
staticクラスのデストラクタは、ソフトウェア終了直前に呼び出される。
void func()
{
static CSampleClass clsSample;
}
// オブジェクトclsSampleは削除されないため、CSampleClassクラスのデストラクタは呼び出されない
実体化の禁止
C++11以降では、デフォルトコンストラクタとデストラクタにdelete
キーワードを指定することにより、実体化を禁止することができる。
メンバにdelete
キーワードを指定する場合は、public
に記述することがセオリーである。
// C++11以降
class CSampleClass final
{
public:
CSampleClass() = delete;
~CSampleClass() = delete;
public:
static int Add(int x, int y)
{
return x + y;
}
};
Visual C++では、abstract
キーワードが使用できるため、abstract sealed
またはabstract final
を指定することにより、static
クラスを記述することができる。
ただし、その場合は、他のプラットフォームではそのまま移植できないことに注意が必要となる。
また、Visual C++では、コンパイルオプションに/permissive-
を付加することにより、独自拡張を無効化することもできる。