static
members
クラス定義内では、キーワード static は、クラスのインスタンスに束縛されないメンバーを宣言します。
クラス定義の外側では、異なる意味を持ちます: storage duration を参照してください。
目次構文静的メンバの宣言は、member declarationであり、その宣言指定子にはキーワード 静的データメンバと静的メンバ関数の名前は、それが属するクラスの名前と異なる必要があります。 説明クラスの静的メンバは、クラスのオブジェクトに関連付けられていません:これらは静的 またはスレッド (C++11以降) ストレージ期間 を持つ独立変数、または通常の関数です。 static キーワードは、クラス定義内での静的メンバーの宣言でのみ使用され、その静的メンバーの定義では使用されません: class X { static int n; }; // 宣言('static'を使用) int X::n = 1; // 定義('static'を使用しない) クラス本体内部での宣言は定義ではなく、メンバが 不完全型 ( void を除く)であることを宣言する場合があります。これには、そのメンバが宣言されている型自体も含まれます: struct Foo; struct S { static int a[]; // 宣言、不完全型 static Foo x; // 宣言、不完全型 static S s; // 宣言、不完全型(自身の定義内) }; int S::a[10]; // 定義、完全型 struct Foo {}; Foo S::x; // 定義、完全型 S S::s; // 定義、完全型
クラスの静的メンバー
struct X { static void f(); // 宣言 static int n; // 宣言 }; X g() { return X(); } // Xを返す関数 void f() { X::f(); // X::fはstaticメンバ関数の修飾名 g().f(); // g().fはstaticメンバ関数を参照するメンバアクセス式 } int X::n = 7; // 定義 void X::f() // 定義 { n = 1; // このスコープではX::nは単にnとしてアクセス可能 } 静的メンバは クラスメンバアクセス規則(private, protected, public) に従います。 静的メンバー関数静的メンバ関数はどのオブジェクトにも関連付けられていません。呼び出された際、これらは this ポインタを持ちません。 静的メンバー関数は virtual 、 const 、 volatile または ref-qualified にすることはできません。 静的メンバー関数のアドレスは通常の 関数ポインタ に格納できますが、 メンバー関数ポインタ には格納できません。 静的データメンバはどのオブジェクトとも関連付けられません。クラスのオブジェクトが定義されていなくても存在します。プログラム全体に静的データメンバのインスタンスはただ一つであり、静的 記憶域期間、ただしキーワード thread_local が使用される場合、その場合はスレッドごとにそのようなオブジェクトが一つ存在し、スレッド記憶域期間(C++11 から)。 静的データメンバは になることはできません 名前空間スコープのクラスの静的データメンバは 外部リンケージ を有する場合、クラス自体が外部リンケージを持つ(無名名前空間)。ローカルクラス(関数内で定義されたクラス)および無名クラス(無名クラスのメンバクラスを含む)は静的データメンバを持つことができません。
定数静的メンバー整数型または列挙型の静的データメンバーが const (かつ volatile ではない)として宣言されている場合、 initializer 内のすべての式が constant expression である初期化子を使用して、クラス定義内で直接初期化することができます: struct X { const static int n = 1; const static int m{2}; // C++11以降 const static int k; }; const int X::k = 3;
const 非インライン (C++17以降) 静的データメンバ またはconstexpr静的データメンバ (C++11以降) (C++17以前) が ODR-use される場合、名前空間スコープでの定義が依然として必要ですが、初期化子を持つことはできません。
struct X { static const int n = 1; static constexpr int m = 4; }; const int *p = &X::n, *q = &X::m; // X::n と X::m は ODR-使用されている const int X::n; // … したがって定義が必要 constexpr int X::m; // … (C++17 では X::m を除く) キーワード不具合報告以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
参考文献
関連項目 |