Programmingバックエンド開発者

C++における静的および非静的クラスメンバーとは何ですか?それらの特徴、初期化方法、使用ルールは何ですか?

Hintsage AIアシスタントで面接を突破

回答。

問題の背景

C++では、クラスは静的および非静的メンバー(変数と関数)を持つことができます。これは、クラスの全てのオブジェクトに共通のデータをサポートするため、また特定のインスタンスの状態にアクセスする必要のない関数のために存在します。

問題

静的メンバーと非静的メンバーは異なるライフサイクル、スコープ、および初期化ルールを持つため、区別することが重要です。一般的な間違いには、誤った定義、インスタンスメンバーと静的メンバーの同時使用、ヘッダーでの再定義が含まれます。

解決策

クラスの静的変数は、クラス内でstaticとして宣言されますが、クラスの外で単独に定義する必要があります(C++17以前)。それらは単一のインスタンスとして存在します。静的関数は、明示的に指定しない限り、非静的(インスタンス)メンバーにアクセスできません。

コード例:

class Counter { public: static int count; Counter() { ++count; } static void Reset() { count = 0; } }; int Counter::count = 0;

主要な特徴:

  • 静的メンバーはクラスの全てのオブジェクト間で状態を共有する
  • クラスのインスタンスを作成せずに静的メンバーを使用できる
  • 静的変数の初期化は、クラスの定義の外で行う(C++17以前)

トリッキーな質問。

C++17以前に、静的メンバー変数をクラス内で直接初期化できますか?

いいえ、C++17以前は、静的メンバーの定義はクラスの外で行う必要があります。C++17以降は、inline staticの場合、クラス内で直接定義することが可能です。

// C++17 class Foo { inline static int counter = 0; };

クラスの静的関数はthisや非静的メンバーにアクセスできますか?

いいえ、静的メンバーは非静的メンバーやthisにアクセスすることはできません。クラスのインスタンスが存在していてもです。アクセスするには明示的にオブジェクトを渡す必要があります。


静的メンバーはクラスの各インスタンスごとに作成されますか?

いいえ、静的メンバーは全クラスに対して単一のインスタンスとして存在し、オブジェクトの数に依存しません。

一般的なエラーおよびアンチパターン

  • 静的メンバーがクラスの外で定義されていない(古い標準)
  • 各オブジェクトに依存するデータを保持するために静的メンバーを使用する
  • グローバル静的変数によるカプセル化の違反

実生活の例

ネガティブケース

開発者がクラス内でstatic intを宣言するが、クラスの外で定義しない。リンカーは未定義シンボルエラーを出します。なぜなら、静的メンバーが初期化されていないからです。

メリット:

  • コンパイラは宣言に対してエラーを出さない

デメリット:

  • リンキングエラー
  • 初期化前に変数が使用されると、謎のランタイムエラーが発生する可能性がある

ポジティブケース

静的メンバーがクラス内で宣言され、クラスの外で定義され、作成されたオブジェクトのカウンターとして使用される。

メリット:

  • 状態の単一のストレージ
  • 明確な初期化と正しい動作

デメリット:

  • マルチスレッド環境における競合状態の可能性(追加の保護が必要)