static メンバー
クラス定義内で、キーワード static は、クラスインスタンスにバインドされないメンバーを宣言します。
クラス定義外では、異なる意味を持ちます。詳しくは記憶域期間を参照してください。
目次 |
[編集] 構文
静的メンバーの宣言は、宣言指定子にキーワード static を含むメンバー宣言です。キーワード static は通常、他の指定子より前に現れます(そのため、構文はしばしば非公式に static データメンバー または static メンバー関数 と記述されますが、指定子のシーケンスのどこに現れても構いません)。
任意の静的データメンバーおよび静的メンバー関数の名前は、含まれるクラスの名前と異なっている必要があります。
[編集] 説明
クラスの静的メンバーは、クラスのオブジェクトに関連付けられていません。これらは静的またはスレッド(C++11以降) 記憶域期間を持つ独立した変数、または通常の関数です。
static キーワードは、クラス定義内の静的メンバーの宣言にのみ使用され、その静的メンバーの定義には使用されません。
class X { static int n; }; // declaration (uses 'static') int X::n = 1; // definition (does not use 'static')
クラス本体内の宣言は定義ではなく、メンバーが不完全型(void 以外)であることを宣言できます。これには、メンバーが宣言されている型も含まれます。
struct Foo; struct S { static int a[]; // declaration, incomplete type static Foo x; // declaration, incomplete type static S s; // declaration, incomplete type (inside its own definition) }; int S::a[10]; // definition, complete type struct Foo {}; Foo S::x; // definition, complete type S S::s; // definition, complete type
|
ただし、宣言がconstexprまたはinline(C++17以降) 指定子を使用する場合、メンバーは完全型であると宣言されなければなりません。 |
(C++11以降) |
クラス T の静的メンバー m を参照するには、2つの形式を使用できます: 修飾名 T::m、またはメンバーアクセス式 E.m または E->m。ここで E はそれぞれ T または T* に評価される式です。同じクラススコープ内では、修飾は不要です。
struct X { static void f(); // declaration static int n; // declaration }; X g() { return X(); } // some function returning X void f() { X::f(); // X::f is a qualified name of static member function g().f(); // g().f is member access expression referring to a static member function } int X::n = 7; // definition void X::f() // definition { n = 1; // X::n is accessible as just n in this scope }
静的メンバーはクラスメンバーアクセスルール (private, protected, public)に従います。
[編集] 静的メンバー関数
静的メンバー関数はどのオブジェクトにも関連付けられていません。呼び出されたとき、それらは this ポインターを持ちません。
静的メンバー関数は virtual、const、volatile、または参照修飾にできません。
静的メンバー関数のアドレスは、通常の関数へのポインターに格納できますが、メンバー関数へのポインターには格納できません。
[編集] 静的データメンバー
静的データメンバーはどのオブジェクトにも関連付けられていません。クラスのオブジェクトが定義されていなくても存在します。プログラム全体で静的データメンバーのインスタンスは1つだけで、静的記憶域期間を持ちます。ただし、キーワード thread_local が使用されている場合は除き、その場合はスレッドごとに1つのオブジェクトがあり、スレッド記憶域期間を持ちます(C++11以降)。
静的データメンバーは mutable にできません。
名前空間スコープ内のクラスの静的データメンバーは、クラス自体が外部リンケージを持つ場合(無名名前空間のメンバーではない場合)、外部リンケージを持ちます。ローカルクラス(関数内で定義されたクラス)および無名クラス(無名クラスのメンバークラスを含む)は、静的データメンバーを持つことができません。
|
静的データメンバーはinlineとして宣言できます。インライン静的データメンバーはクラス定義内で定義でき、初期化子を指定できます。クラス外での定義は不要です。 struct X { inline static int fully_usable = 1; // No out-of-class definition required, ODR-usable inline static const std::string class_name{"X"}; // Likewise static const int non_addressable = 1; // C.f. non-inline constants, usable // for its value, but not ODR-usable // static const std::string class_name{"X"}; // Non-integral declaration of this // form is disallowed entirely }; |
(C++17以降) |
[編集] 定数静的メンバー
整数型または列挙型の静的データメンバーが const (かつ volatile ではない) と宣言されている場合、クラス定義内で、すべての式が定数式である初期化子で初期化できます。
struct X { const static int n = 1; const static int m{2}; // since C++11 const static int k; }; const int X::k = 3;
|
LiteralType の静的データメンバーが constexpr と宣言されている場合、クラス定義内で、すべての式が定数式である初期化子で初期化されなければなりません。 struct X { constexpr static int arr[] = { 1, 2, 3 }; // OK constexpr static std::complex<double> n = {1,2}; // OK constexpr static int k; // Error: constexpr static requires an initializer }; |
(C++11以降) |
const 非インライン(C++17以降) 静的データメンバーまたは constexpr 静的データメンバー(C++11以降)(C++17まで) がODR-useされている場合、名前空間スコープでの定義は依然として必要ですが、初期化子を持つことはできません。
|
constexpr 静的データメンバーは暗黙的に inline であり、名前空間スコープで再宣言する必要はありません。この初期化子なしの再宣言(以前は必須でした)はまだ許可されていますが、非推奨です。 |
(C++17以降) |
struct X { static const int n = 1; static constexpr int m = 4; }; const int *p = &X::n, *q = &X::m; // X::n and X::m are ODR-used const int X::n; // … so a definition is necessary constexpr int X::m; // … (except for X::m in C++17)
[編集] キーワード
[編集] 欠陥レポート
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| CWG 194 | C++98 | (static) メンバー関数名はクラス名と同じにすることができます | 命名制限が追加されました(以下を含む 非静的メンバー関数) |
[編集] 参照
- C++23標準 (ISO/IEC 14882:2024)
- 11.4.9 静的メンバー [class.static]
- C++20 standard (ISO/IEC 14882:2020)
- 11.4.8 静的メンバー [class.static]
- C++17 standard (ISO/IEC 14882:2017)
- 12.2.3 静的メンバー [class.static]
- C++14 standard (ISO/IEC 14882:2014)
- 9.4 静的メンバー [class.static]
- C++11 standard (ISO/IEC 14882:2011)
- 9.4 静的メンバー [class.static]
- C++98 標準 (ISO/IEC 14882:1998)
- 9.4 静的メンバー [class.static]