道は邪魔で長く、線が来ています。頭を下げて一生懸命頑張ってください。話さなければ、あなたは大ヒット作になります!さあ、サンニアン!
参照
「C ++ Primer Fifth Edition」ページ268、セクション7.6:クラスの静的メンバー。
「C ++ Primer Fifth Edition」250ページ、セクション7.3.3:クラスタイプ。
テキストの始まり
なぜクラスの静的メンバーが必要なのですか?
クラスのメンバーによっては、クラスのさまざまなオブジェクトとの関連付けを維持するのではなく、クラス自体に直接関連している必要がある場合があります。
たとえば、銀行口座クラスは、現在のベンチマーク金利を表すためにデータメンバーを必要とする場合があります。
この場合、金利はクラスに直接関連付けられており、各オブジェクトはクラスに関連付けられていません。
次の2つの角度から見ることができます。
- 実装効率の観点からは、各オブジェクトが金利情報を格納する必要はありません。
- さらに重要なことは、金利が変動したら、すべてのオブジェクトに新しい値を使用することです。
静的メンバーを宣言する方法は?
メンバーの前のステートメントに、キーワードstatic
を追加して、クラスに関連付けます。
次の側面に注意を払う必要があります:
-
静的メンバーは
public
またはprivate
です。 -
静的データメンバーの型には、定数、参照、ポインター、クラス型などがあります。
-
クラスの静的メンバーはオブジェクトの外部に存在し、オブジェクトには静的データメンバーに関連するデータが含まれていません。
例えば:
- 犬のカテゴリでは、各犬に4本の足があり、私のメンバーをこのカテゴリに関連付けることができます。
- これによって作成されたすべてのオブジェクトはこのメンバーを使用できます(これによって作成された各犬には4本の足があります)。
- このクラスを使用するすべての犬のメンバーを作成して、4本の足があることを伝える必要はありません。
-
静的メンバー関数は、どのオブジェクトにも一緒にバインドされておらず、
this
ポインターが含まれていません。 -
その結果、静的メンバー関数として宣言することはできませんが、関数ポインターの本体を使用する
const
こともできません。static
this
この制限は両方に適用され、
this
明示的な使用は暗黙的な呼び出しの非静的メンバーの使用にも効果的です。
クラスの静的メンバーの使用方法は?
スコープ演算子 "::"を使用して、静的メンバーに直接アクセスします。
a::b();
静的メンバーはクラスのオブジェクトに属していませんが、クラスのオブジェクト、参照、またはポインターを使用して静的メンバーにアクセスできます。
メンバー関数は、スコープ演算子を経由せずに静的メンバーを直接使用できます。
静的メンバーを定義する方法は?
クラスの内部と外部の両方で静的メンバー関数を定義できます。
外部静的メンバーがクラスで定義されている場合、クラス内static
での宣言のみが出現するキーワードを繰り返すことはできません。
注意:
クラスのすべてのメンバーと同様に、クラスの外部の静的メンバーを指す場合、メンバーが属するクラスの名前を指定する必要があります。
static
キーワードは、クラス内の宣言ステートメントにのみ表示されます。
静的データメンバーはクラスのどのオブジェクトにも属していないため、クラスのオブジェクトの作成時に定義されません。これは、それらがクラスのコンストラクターによって初期化されないことを意味します。
一般的に、クラス内の静的メンバーを初期化することはできません。クラス外の各静的メンバーを定義して初期化する必要があります。他のオブジェクトと同様に、静的データメンバーは一度だけ定義できます。
グローバル変数と同様に、静的データメンバーは関数の外部で定義されます。したがって、いったん定義すると、プログラムのライフサイクル全体で常に存在します。
静的データメンバーを定義する方法は、クラスの外部でメンバー関数を定義する方法と似ています。オブジェクトのタイプ名を指定し、次にクラス名、スコープ演算子、およびメンバー自体の名前を指定する必要があります。
double Account::interestRate = initRate();
このステートメントは、名前付きinterestRate
オブジェクトを定義します。そのオブジェクトは、Account
そのタイプのクラス静的メンバーですdouble
。
クラス名から始めて、残りの定義ステートメントはクラスのスコープ内にあります。したがって、initRate()
関数を直接使用できます。
注意:
が
initRate
プライベート、我々はまた、初期化するためにそれを使用することができますinterestRate
。他のメンバーの定義と同様に、定義
interestRate
もクラスのプライベートメンバーにアクセスできます。
オブジェクトが1回だけ定義されるようにするための最良の方法は、静的データメンバーの定義と他の非インライン関数の定義を同じファイルに置くことです。
静的メンバーのクラス内初期化
通常、クラスの静的メンバーは、クラス内で初期化しないでください。ただし、const
整数型の初期値のクラス内で静的メンバーを提供できますが、静的メンバーはリテラル定数型である必要がありますconstexpr
。
これらのメンバー自体は定数式であるため、初期値は定数式でなければなりません。定数式に適したすべての場所で使用できます。
class Account
{
public:
static double rate() {
return interestRate;}
static void rate(double);
private:
static constexpr int period = 30; // period 是常量表达式
double daily_tbl[period];
};
定数静的データメンバーがクラス内で初期化されている場合でも、通常、メンバーはクラス外で定義する必要があります。
静的メンバーは特定のシナリオで使用できますが、通常のメンバーは使用できません
-
静的メンバーは、オブジェクトから独立しています。
-
非静的データメンバーが不正である可能性がある状況では、静的メンバーを通常どおり使用できます。
-
静的データメンバーは不完全な型になる可能性があります(拡張情報の簡単な紹介)。
特に、静的データメンバーのタイプは、それが属するクラスのタイプにすることができます。非静的データメンバーは制限されており、それらが属するクラスへのポインターまたは参照としてのみ宣言できます。
class Bar
{
public:
// ...
private:
static Bar mem1; // 正确:静态成员可以是不完全类型
Bar *mem2; // 正确:指针成员可以是不完全类型
Bar mem3; // 错误:数据成员必须是完全类型
};
静的メンバーと通常のメンバーのもう1つの違いは、静的メンバーをデフォルト引数として使用できることです。
class Screen
{
public:
// bkground 表示一个在类中稍后定义的静态成员
Screen& clear(char = bkground);
private:
static const char bkground;
};
非静的データメンバーは、その値自体がオブジェクトの一部であるため、デフォルト引数として使用できません。その結果、オブジェクトからメンバーの値を取得するためのオブジェクトを提供できず、最終的にエラーが発生します。
詳細情報
不完全なタイプ
以下に示すように、アナログ関数の宣言を定義から分離することも、一時的に定義せずにクラスを宣言することもできます。
class Screen; // Screen 类的声明
このステートメントは、前方宣言と呼ばれることもあり、プログラムの名前に導入され、クラスタイプScreen
を示しますScreen
。
typeのScreen
場合、その前のステートメントは不完全なtypeの後に定義されます。つまり、現時点でScreen
はクラス型であることがわかりますが、結局、どのメンバーが含まれているかは明確ではありません。
不完全な型は、非常に限られた状況でのみ使用できます。この型へのポインターまたは参照を定義するか、不完全な型をパラメーターまたは戻り型として取る関数を宣言できます(ただし定義はできません)。
記事の内容が間違っている場合は、コメント/プライベートメッセージをたくさんアドバイスしてください、ありがとう!記事の内容に問題がないと思われる場合は、3つのリンク(ブックマーク、メッセージを残すなど)をクリックすることを忘れないでください。サポートが私の最大の励みです。ありがとうございます!