12

ここにいくつかのコードがあります:

class MyClass
{
public:
    int y;
};

int main()
{
    MyClass item1;
    MyClass item2 = MyClass();
}

これを実行すると、次の値を受け取ります。

item1.y == [garbage]
item2.y == 0

それは、まあ、私を驚かせます。

item1 がデフォルトで構築され、item2 が MyClass の匿名のデフォルトで構築されたインスタンスからコピー構築されることを期待した結果、両方とも 0 になります (デフォルト コンストラクターはメンバーをデフォルト値に初期化するため)。アセンブリの検査:

//MyClass item1;
//MyClass item2 = MyClass();
xor         eax,eax  
mov         dword ptr [ebp-128h],eax  
mov         ecx,dword ptr [ebp-128h]  
mov         dword ptr [item2],ecx  

item2 は、一時的な場所に「0」値を書き込み、それを item2 にコピーすることによって構築されていることを示しています。ただし、item1 のアセンブリはありません。

したがって、プログラムは item1 のメモリをスタックに持っていますが、item1 を構築することはありません。

速度のためにその動作を望んでいることは理解できますが、両方の長所が欲しいのです! item1.y == 0 (構築されます) を知りたいのですが、item2 のように default-construct-anonymous-instance-then-copy-construct で時間を無駄にしたくありません。

MyClass item1();イライラすることに、関数プロトタイプとして解釈されるため、デフォルト構成を強制することはできません。

だから...コピー構築もせずにitem1でデフォルトのコンストラクターを使用したい場合、どうすればいいのでしょうか?

補足: MyClass のコンストラクターを宣言すると、item1 が通常どおりに構築されるように見えます。したがって、この動作は、コンパイラによって生成されたコンストラクターにのみ適用されます。

4

4 に答える 4

16

クラスを次のようにします。

class MyClass 
{
public:
    MyClass() : y(0) 
    {
    }

public:
    int y;
};

どちらの例も問題なく動作します。問題は、コンストラクターが指定されていない場合、基本型メンバーが初期化されないことです。yが存在する場所のスタックにたまたまあるランダムなデータを表すこともそうですitem1

コンストラクターを明示的に実装すると、これに対処できます。

この動作が存在するのは、C++ の「使用した分だけ支払う」という考え方によるものです。基本型には「デフォルト値」がありません。これは、値が実質的に 2 回設定されるため、何かを割り当ててから後で入力するのに不必要に (わずかに) コストがかかるためです。「デフォルト値」に対して1回、実際に必要な値に対して1回。

于 2013-10-28T03:03:17.053 に答える
2

あなたは簡単に行うことができます:

MyClass item1;

変数に応じて、POD タイプをゼロ初期化する場合とそうでない場合があります。

または、C++11 を使用している場合は、次のことができます。

MyClass item1 {};

デフォルトのコンストラクターを明示的に呼び出します。

item1 のアセンブリ コードがない理由は、明示的なデフォルト コンストラクターが記述されていないため、示されているようなクラスのコードを生成する必要がないとコンパイラーが判断したためです。

于 2013-10-28T02:49:56.460 に答える