10

C++ の初期化に関する Google の投稿をいくつか読みました。これらの投稿から私が選んだコンセプトは次のとおりです。

  • C++ の初期化 の順序は次のとおりです。
    1. ゼロ初期化;
    2. 静的初期化;
    3. 動的初期化
  • 静的オブジェクト(変数を含む) は、最初にZero-initializedであり、次にStatic-initializedです。

初期化の問題についていくつか問い合わせがあります(ストレージ クラスの問題も関連している可能性があります)。

  • グローバル オブジェクト( staticキーワードなしで定義) も静的オブジェクトですよね?
  • グローバル オブジェクト静的オブジェクトのように、上記のように 2 段階で初期化されますね。
  • 静的初期化とは何ですか? 静的オブジェクト ( staticキーワードで定義) の初期化を参照していますか?
  • また、静的キーワードを使用してブロック内 (つまり関数内) で定義されたオブジェクトは、実行スレッドが最初にブロックに入ったときに初期化されることも読みました! これは、main関数の実行前にローカルの静的オブジェクトが初期化されないことを意味します。これは、上記の 2 つの手順のように初期化されていないことを意味しますよね?
  • 動的初期化とは、 new演算子によって作成されたオブジェクトの初期化を指しますよね? myClass obj = myClass(100);またはのような初期化を参照する場合がありますmyClass obj = foo();

初期化とストレージ クラス指定子の問題に関する問い合わせが多すぎます。C++2003 標準ドキュメントを読みましたが、ドキュメント全体に散らばっているため、明確なロジックを見つけることができません。

ストレージ クラス指定子と初期化のマップ全体を論理的に説明する回答をいただければ幸いです。どなたでも参考にどうぞ!

私の質問を説明するかもしれないコード:

class myClass{
public:
   int i;
   myClass(int j = 10): j(i){}
   // other declarations
};

myClass obj1;//global scope
static myClass obj2(2);//file scope
{   //local scope
   myClass obj3(3);
   static myClass obj4(4);
}

編集:
私の質問がかなり退屈だと思う場合は、上記のコードに基づいてアイデアを説明するのに役立ちます。

4

2 に答える 2

20

C++ の初期化に関する Google の投稿をいくつか読みました。これらの投稿から私が選んだコンセプトは次のとおりです。

  • C++ の初期化 の順序は次のとおりです。
    1. ゼロ初期化;
    2. 静的初期化;
    3. 動的初期化

はい、確かに 3 つのフェーズがあります (標準では)。続行する前に、それらを明確にしましょう。

  • ゼロ初期化: メモリはバイト レベルで 0 で埋められます。
  • 定数の初期化: 事前に計算された (コンパイル時) バイト パターンがオブジェクトのメモリ位置にコピーされます。
  • 静的初期化: ゼロ初期化とそれに続く定数初期化
  • 動的初期化: メモリを初期化する関数が実行されます

簡単な例:

int const i = 5;     // constant initialization
int const j = foo(); // dynamic initialization
  • 静的オブジェクト(変数を含む) は、最初にZero-initializedであり、次にStatic-initializedです。

はいといいえ。

標準では、オブジェクトが最初にゼロで初期化され、次に次のようになることが義務付けられています。

  • 可能であれば定数を初期化
  • それ以外の場合は動的に初期化されます (コンパイラはコンパイル時にメモリの内容を計算できませんでした)

注: 定数の初期化の場合、コンパイラは、as-if ルールに従って、ゼロで初期化された最初のメモリを省略する場合があります。

初期化の問題についていくつか問い合わせがあります(ストレージ クラスの問題も関連している可能性があります)。

  • グローバル オブジェクト( staticキーワードなしで定義) も静的オブジェクトですよね?

はい、ファイルスコープでは、staticオブジェクトはシンボルの可視性に関するものです。グローバル オブジェクトは別のソース ファイルから名前で参照できますが、staticオブジェクト名は現在のソース ファイルに対して完全にローカルです。

static混乱は、さまざまな状況での世界の再利用に起因します:(

  • グローバル オブジェクト静的オブジェクトのように、上記のように 2 段階で初期化されますね。

はい、実際にはローカル静的オブジェクトと同様です。

  • 静的初期化とは何ですか? 静的オブジェクト ( staticキーワードで定義) の初期化を参照していますか?

いいえ、上で説明したように、ユーザー定義関数を実行せずにオブジェクトを初期化することを指しますが、代わりに事前計算されたバイト パターンをオブジェクトのメモリにコピーします。後で動的に初期化されるオブジェクトの場合、これはメモリをゼロにするだけであることに注意してください。

  • また、静的キーワードを使用してブロック内 (つまり関数内) で定義されたオブジェクトは、実行スレッドが最初にブロックに入ったときに初期化されることも読みました! これは、メイン関数の実行前にローカルの静的オブジェクトが初期化されないことを意味します。これは、上記の 2 つの手順のように初期化されていないことを意味しますよね?

これらは 2 段階のプロセスで初期化されますが、実際には最初の実行のみが定義を通過します。プロセスは同じですが、タイミングが微妙に異なります。

ただし実際には、それらの初期化が静的であり (つまり、メモリ パターンがコンパイル時のパターンである)、それらのアドレスが取得されない場合、それらは最適化されて削除される可能性があります。

動的初期化の場合、初期化が失敗した場合 (それらを初期化するはずの関数によって例外がスローされた場合)、次にフロー制御がそれらの定義を通過するときに再試行されることに注意してください。

  • 動的初期化とは、 new演算子によって作成されたオブジェクトの初期化を指しますよね? myClass obj = myClass(100);またはのような初期化を参照する場合がありますmyClass obj = foo();

まったくありません。ユーザー定義関数の実行を必要とする初期化を指します (注: std::stringC++ 言語に関する限り、ユーザー定義のコンストラクターがあります)。

編集:私を指摘してくれたザックに感謝します.C++ 11標準が定数初期化と呼んでいるものを誤って静的初期化と呼びました。このエラーは修正されるはずです。

于 2013-07-23T07:12:13.933 に答える