ProgrammingC++バックエンド開発者

staticメンバー(変数および関数)のクラス内での動作について説明してください。staticメンバーはどのように初期化され、定義と使用においてどのような問題が発生し、staticメンバーは通常のクラスメンバーとどのように異なりますか?

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

回答

クラスのstaticメンバーは、クラス全体に対して単一のインスタンスとして存在し、全てのオブジェクトに共通の値です。

  • static変数はクラスの外で初期化され、通常はcppファイル内で、クラスの外で行われます(int Foo::count = 0;)。クラス内では宣言し、外で定義します
  • static関数はクラスおよびオブジェクトの両方から呼び出すことができます。特定のインスタンスのメンバー(this)にアクセスすることはできず、他のstaticメンバーにのみアクセスできます。

コード例

class Counter { public: static int count; static void increment() { ++count; } }; int Counter::count = 0; int main() { Counter::increment(); Counter c1, c2; c1.increment(); // count == 2 }

トリックな質問

「staticメンバーの定義はヘッダーファイルの中に含めることができますか?どんなリスクがありますか?」

回答: はい、定義(int Foo::value = 0;)をヘッダー内に含めることは技術的には可能ですが、そのヘッダーが複数の翻訳単位でインクルードされると、重複定義(multiple definition)を引き起こし、リンクエラーが発生します。したがって、staticメンバーは必ず1つのcppファイルの中でのみ定義するべきです。


このテーマに関する知識不足からくる実際のエラーの例。


物語

ライブラリコードでstaticメンバーが直接ヘッダーファイル内で定義されていました。複数のインクルードがリンクエラー「multiple definition of ...」を引き起こしました。定義を別のcppファイルに移動した後、問題は解消されました。


物語

教育プロジェクトではstaticメンバーが宣言されましたが、外部のcppファイルで定義するのを忘れました。ヘッダーのコンパイルエラーはなかったものの、リンク時に未解決の外部シンボルエラーが発生しました。欠けている定義を探して追加する必要がありました。


物語

大型の組み込みシステムで、計算値を持つstaticメンバーの初期化を誤って実装しました(コードの実行を必要とする式を使用して初期化しようとしました)。ロジックを別の初期化関数に分離しましたが、最初のアクセスの前にこの関数を呼び出すのをうっかり忘れ、その結果、初期化されていない変数と異常動作が発生しました。