const で定義された定数は、そのスコープを超えるとその空間は解放されますが、static で定義された静的定数は関数の実行後もその記憶領域は解放されません。
static は静的を意味します。クラスの静的メンバー関数、静的メンバー変数はクラスに関連しており、クラスの具体的なオブジェクトには関連していません。具体的なオブジェクトがなくても、クラスの静的メンバー関数とメンバー変数を呼び出すことができます。一般的に、クラスの静的関数はほぼグローバル関数ですが、そのスコープがそれを含むファイル内に限定されているだけです。
C++ では、static 静的メンバー変数はクラスの内部で初期化できません。クラスの内部では宣言のみであり、定義はクラス定義本体の外部で行う必要があります。通常はクラスの実装ファイルで初期化します。例:double Account::Rate = 2.25;
static キーワードはクラス定義体内部の宣言にのみ使用でき、定義時に static と指定することはできません。
C++ では、const メンバー変数もクラス定義の場所で初期化できず、コンストラクタの初期化リストによってのみ初期化でき、コンストラクタが必要です。
const データメンバーは、あるオブジェクトの生存期間内でのみ定数であり、クラス全体としては変更可能です。クラスは複数のオブジェクトを作成できるため、異なるオブジェクトの const データメンバーの値は異なる場合があります。そのため、クラスの宣言内で const データメンバーを初期化することはできません。クラスのオブジェクトが作成されていないとき、コンパイラは const データメンバーの値が何であるかを知らないからです。
const データメンバーの初期化は、クラスのコンストラクタの初期化リストでのみ行えます。クラス全体で一定の定数を確立したい場合は、クラス内の列挙型定数を使用するか、static const を使用して実現する必要があります。
const メンバー関数の主な目的は、メンバー関数がオブジェクトの内容を変更するのを防ぐことです。つまり、const メンバー関数はメンバー変数の値を変更できませんが、メンバー変数にアクセスすることはできます。メンバー関数を const として宣言する場合、その関数は const メンバー関数でなければなりません。
static メンバー関数の主な目的は、クラススコープのグローバル関数として機能することです。クラスの非静的データメンバーにアクセスできません。クラスの静的メンバー関数には this ポインタがないため、次の結果が生じます:
- 1. クラスの非静的メンバー変数に直接アクセスしたり、非静的メンバー関数を呼び出したりすることができません。
- 2. virtual として宣言することができません。
static、const、static const、const static メンバーの初期化問題について
1. クラス内の const メンバーの初期化:
クラス内で const を設定する場合、それに初期値を与えることはできません。
2. クラス内の static メンバーの初期化:
クラス内の static 変数はクラスに属し、特定のオブジェクトには属しません。プログラム全体の実行中にコピーは1つだけです。そのため、オブジェクトを定義するときに変数を初期化することはできません。つまり、コンストラクタで初期化することはできません。正しい初期化方法は次のとおりです:
データ型 クラス名::静的データメンバ名=値;
これは次のことを示しています:
- 1. 初期化はクラス外で行い、先頭に static を付けません。通常の静的変数やオブジェクトと混同しないようにするためです。
- 2. 初期化時には、そのメンバーのアクセス権限の制御指定子(private、public など)を付けません。
3. クラス内の static const と const static メンバーの初期化
この2つの書き方の効果は同じです。覚えやすいように、ここでは一般的な初期化方法を1つだけ説明します。
完全な例
例
初期化位置
静的メンバーはクラスの定義内で初期化できません(int を除く)。ヘッダーファイル内では初期化できません。
例えば、myclass.h を定義した場合、通常は myclass.cpp 内でそれを初期化します。
C++ クラスの静的メンバー(static)
静的メンバーが導入されたのは、データ共有の問題を解決するためです。共有を実現するには多くの方法があります。例えば、グローバルな変数やオブジェクトを設定する方法があります。しかし、グローバル変数やオブジェクトには限界があります。この章では、主にクラスの静的メンバーを使用してデータ共有を実現する方法について説明します。
静的データメンバー
クラス内では、静的メンバーによって複数のオブジェクト間でのデータ共有を実現でき、静的データメンバーを使用しても隠蔽の原則を破壊しません。つまり安全性が保証されます。したがって、静的メンバーはクラスのすべてのオブジェクト間で共有されるメンバーであり、特定のオブジェクトのメンバーではありません。
静的データメンバーを使用するとメモリを節約できます。すべてのオブジェクトに共通のものであるため、複数のオブジェクトに対して静的データメンバーは1か所にのみ格納され、すべてのオブジェクトで共用されます。静的データメンバーの値は各オブジェクトで同じですが、その値は更新できます。静的データメンバーの値を一度更新するだけで、すべてのオブジェクトが更新後の同じ値にアクセスすることが保証されるため、時間効率が向上します。
静的データメンバーの使用方法と注意事項は次のとおりです:
1. 静的データメンバーは、定義または説明の際に先頭にキーワード static を付けます。
2. 静的メンバーの初期化は、通常のデータメンバーの初期化とは異なります。静的データメンバーの初期化の形式は次のとおりです:
<データ型><クラス名>::<静的データメンバ名>=<値>
これは次のことを示しています:
- (1) 初期化はクラス外で行い、先頭に static を付けません。通常の静的変数やオブジェクトと混同しないようにするためです。
- (2) 初期化時には、そのメンバーのアクセス権限制御指定子(private、public など)を付けません。
- (3) 初期化時にはスコープ演算子を使用して、それが所属するクラスを示します。したがって、静的データメンバーはクラスのメンバーであり、オブジェクトのメンバーではありません。
3. 静的データメンバーは静的記憶域を持ち、静的生存期間です。必ず初期化する必要があります。
4. 静的データメンバーを参照する場合、次の形式を使用します:
<クラス名>::<静的メンバ名>
静的データメンバーのアクセス権限が許可されていれば(つまり public メンバーの場合)、プログラム内で上記の形式に従って静的データメンバーを参照できます。
次に、静的データメンバーの応用を説明する例を示します:
例
出力結果から、Sum の値は M オブジェクトでも N オブジェクトでも等しいことがわかります。これは、M オブジェクトを初期化するときに、M オブジェクトの3つの int 型データメンバーの値の合計が Sum に代入され、Sum がその値を保存するためです。N オブジェクトを初期化するときに、N オブジェクトの3つの int 型データメンバーの値の合計が Sum の既存の値に加算され、Sum は更新後の値を保存します。したがって、オブジェクト M を介して参照しても、オブジェクト N を介して参照しても、値は同じ、つまり54になります。
静的メンバー関数
静的メンバー関数は静的データメンバーと同様に、どちらもクラスの静的メンバーに属し、どちらもオブジェクトのメンバーではありません。そのため、静的メンバーの参照にはオブジェクト名は必要ありません。
静的メンバー関数の実装では、クラス内で宣言された非静的メンバーを直接参照できませんが、クラス内で宣言された静的メンバーは参照できます。静的メンバー関数内で非静的メンバーを参照する必要がある場合は、オブジェクトを介して参照できます。以下に例を示して説明します。
例
読者は自分でその結果を分析できます。これからわかるように、静的メンバー関数の呼び出しには次の形式を使用します:
<クラス名>::<静的メンバ関数名>(<引数表>);
C++ における各種タイプのメンバー変数の初期化方法
C++ のさまざまなタイプのメンバーは、static であるかどうか、const であるかどうかによって、初期化方法が異なります。Java の構文はそれほど複雑ではないので、多くの人が Java を学びに行くのも無理はありません。以前、面接でこの問題を聞かれて答えられず、コードを書くときもよく混乱していました。ここでは本を調べてまとめます。
一部のメンバー変数のデータ型は特殊で、その初期化方法も通常のデータ型のメンバー変数とは異なります。これらの特殊な型のメンバー変数には次のものがあります:
- a. 定数型メンバー変数
- b. 参照型メンバー変数
- c. 静的メンバー変数
- d. 整数型の静的定数メンバー変数
- e. 非整数型の静的定数メンバー変数
定数型メンバー変数と参照型メンバー変数の初期化は、コンストラクタの初期化リストによって行う必要があります。コンストラクタ本体で定数型メンバー変数や参照型メンバー変数に代入する方法は通用しません。
静的メンバー変数の初期化もかなり特別です。
以下のコードとその中のコメントを参照してください:
C++ 静的メンバーまとめ、C++、static
クラスの静的メンバーは本当に愛憎相半ばする特性です。かつて面接で、面接官にこの問題を徹底的に追及され、顔を真っ赤にして敗北したことがあります。それで帰ってから、悔しさを胸に刻み、静的クラスメンバーの知識ポイントをしっかりまとめて、今後の面接でこの種の問題に受動的にならないようにしようと決めました。
静的クラスメンバーは、静的データメンバーと静的関数メンバーの2つの部分から構成されます。
静的データメンバー
クラス本体のデータメンバーの宣言の前にstaticキーワードを付けると、そのデータメンバーはそのクラスの静的データメンバーになります。他のデータメンバーと同様に、静的データメンバーもpublic/protected/privateのアクセス規則に従います。また、静的データメンバーには以下の特徴があります:
1. 静的データメンバーの定義。
静的データメンバーは実際にはクラススコープ内のグローバル変数です。したがって、静的データメンバーの定義(初期化)はヘッダーファイルに置くべきではありません。(宣言 vs. 定義(初期化))その定義方法はグローバル変数と同じです。例は以下の通りです:
注:ヘッダーファイルで静的データメンバーを定義(初期化)しようとしないでください。ほとんどの場合、これを行うと再定義エラーが発生します。たとえ#ifndef #define #endifまたは#pragma onceを付けてもダメです。
2. 静的データメンバーはクラスのすべてのオブジェクトによって共有されます。これにはそのクラスの派生クラスのオブジェクトも含まれます。つまり、派生クラスのオブジェクトは基底クラスのオブジェクトと基底クラスの静的データメンバーを共有します。例は以下の通りです:
3. 静的データメンバーはメンバー関数のデフォルト引数にできますが、通常のデータメンバーはできません。例は以下の通りです:
4. 静的データメンバーの型は所属クラスの型にできますが、通常のデータメンバーはできません。通常のデータメンバーは所属クラス型のポインタまたは参照としてのみ宣言できます。例は以下の通りです:
5. この特性が標準C++のものなのか、VC6独自のものなのかはわかりません。
静的データメンバーの値はconstメンバー関数内で合法的に変更できます。例は以下の通りです:
静的メンバー関数
静的メンバー関数にはそれほど多くの説明事項はありません。
1. 静的メンバー関数のアドレスは通常の関数ポインタに格納できますが、通常のメンバー関数のアドレスはクラスメンバー関数ポインタに格納する必要があります。例は以下の通りです:
2. 静的メンバー関数はクラスの非静的メンバーを呼び出すことはできません。静的メンバー関数はthisポインタを持たないためです。
3. 静的メンバー関数はvirtual、const、volatile関数として同時に宣言することはできません。例は以下の通りです:
最後に一点、静的メンバーは独立してアクセスできます。つまり、オブジェクトインスタンスを一切作成しなくてもアクセスできます。
作者:SDMrFeng
原文:https://blog.csdn.net/tobefxz/article/details/14109697