C++ のクラスで既定のコンストラクターまたはその他のコンストラクターを定義しない場合、コンパイラーが既定のコンストラクターを作成することを読みました。しかし、テスト クラスを作成し、それをアセンブリ コードにコンパイルして、何も作成されていないことを確認しました。
デフォルトのコンストラクターのコードがどのように作成されるか、または最初に作成されるかどうかを誰かが明確にすることはできますか?
4 に答える
デフォルトのコンストラクターは、必要に応じて作成されます。例:
class Foo {
std::string s;
};
...
Foo f;
12.1:
デフォルトのコンストラクター(12.1)、コピーコンストラクターとコピー代入演算子(12.8)、およびデストラクタ(12.4)は、特別なメンバー関数です。実装は、12.1に記載されている場合を除き、プログラムが明示的に宣言していない場合、クラス型に対してこれらのメンバー関数を暗黙的に宣言します。12.1、12.4、および12.8で指定されているように、実装では、それらが使用されている場合は暗黙的に定義されます。
また、クラスでコンストラクターで何も実行する必要がない場合、標準ではコンストラクターが存在するはずですが、コンパイラーはコードを生成しないことを選択する場合があります。
C ++!=アセンブリ。
アセンブリは、コンパイルされたC ++プログラムの(可能な1つの)出力であり、空のコンストラクターの呼び出しを省略した可能性のある特定の最適化が含まれている場合と含まれていない場合があります。
言い換えれば、言語はデフォルトのコンストラクターが大丈夫だと言っていますが、それは動作のみを記述し、実装は記述していません。実装がコードを生成する必要がないと感じた場合は、生成する必要はありません。
C++03 標準の内容は次のとおりです。
§12.1/5:
クラス X のデフォルトのコンストラクターは、引数なしで呼び出すことができるクラス X のコンストラクターです。クラス X に対してユーザーが宣言したコンストラクターがない場合は、既定のコンストラクターが暗黙的に宣言されます。暗黙的に宣言された既定のコンストラクターは、そのクラスのインライン パブリック メンバーです。暗黙的に宣言されたデフォルトのコンストラクターであり、次の場合、コンストラクターは自明です。
- そのクラスには仮想関数 (10.3) も仮想基本クラス (10.1) もありません。
- そのクラスの直接の基底クラスはすべて自明なコンストラクターを持ち、
- クラス型 (またはその配列) であるそのクラスのすべての非静的データ メンバーに対して、そのような各クラスには自明なコンストラクターがあります。
§12.1/6:
それ以外の場合、コンストラクターは自明ではありません。
§12.1/7:
クラスの暗黙的に宣言された既定のコンストラクターは、そのクラス型 (1.8) のオブジェクトを作成するために使用されるときに暗黙的に定義されます。暗黙的に定義された既定のコンストラクターは、空の mem-initializer-list (12.6.2) と空の関数本体を使用して、そのクラスのユーザー作成の既定のコンストラクターによって実行されるクラスの初期化のセットを実行します。そのユーザー作成のデフォルト コンストラクターの形式が正しくない場合、プログラムは形式が正しくありません。クラスの暗黙的に宣言された既定のコンストラクターが暗黙的に定義される前に、その基底クラスとその非静的データ メンバーのすべての暗黙的に宣言された既定のコンストラクターが暗黙的に定義されている必要があります。[注: 暗黙的に宣言されたデフォルト コンストラクタには、例外仕様 (15.4) があります。]
これは、暗黙的に宣言されているが暗黙的に定義されていないデフォルト コンストラクターを持つクラス、または暗黙的に定義された自明なデフォルト コンストラクターを持つクラスの場合、コード生成が必要ない可能性があることを意味します。
コンパイラが実際にデフォルト コンストラクターのコードを発行するかどうかを確認したいですか?
それは最適化に依存します。最新のコンパイラのほとんどは、-O0 を指定して使用するとデフォルトのコンストラクタ コード シーケンスを出力しますが、それが使用されておらず、-O2 以上を使用すると、それを最適化して削除します。