28

次のクラスを考えてみましょう

class test1
{
    private:
        int a;
        int b;
    public:
        test1():a(0),b(0){}
};

class test2
{
    private:
        int a;
        int b;
    public:
        test2()
        {
            a=0;
            b=0;
        }
};

test1()これで、コンストラクターが a のデータ メンバーを初期化する正しい方法であることがわかりました。これは、初期化ではなく代入を実行classしているためです。test2()私の質問は次のとおりです。

  1. 初期化の代わりに代入を実行すると何がうまくいかないのでしょうか?
  2. test1()コンストラクタの場合、コンパイラは内部的に代入を行いませんか? そうでない場合、これらはどのように初期化されますか?
4

4 に答える 4

27

初期化の代わりに代入を実行すると何がうまくいかないのでしょうか?

一部のクラス タイプ (および参照とconstオブジェクト) は割り当てることができません。一部はデフォルトで初期化できません。直接初期化するよりも、デフォルトで初期化して再割り当てする方がコストがかかるものもあります。

test1() コンストラクタの場合、コンパイラは内部的に割り当てを実行しませんか? いいえの場合、これらはどのように初期化されますか?

のようなプリミティブ型の場合、int両者の間に実質的な違いはほとんどないか、まったくありません。デフォルトの初期化は何もせず、直接の初期化と割り当ては本質的に同じことを行います。

クラス型の場合、デフォルト初期化、割り当て、および直接初期化はそれぞれ異なるユーザー定義関数を呼び出し、一部の操作はまったく存在しない場合があります。したがって、一般に、2 つの例は非常に異なる動作をする可能性があります。

于 2013-03-28T12:08:12.770 に答える
17

あなたの例では、プレーンな整数を初期化しているため、実際の違いはありません。

ただし、これらの整数がコンストラクターを持つオブジェクトであると仮定すると、コンパイラーは次の呼び出しを生成します。

// test1
a::copy_constructor(0);
b::copy_constructor(0);


// test2
a::default_constructor();
b::default_constructor();
a::operator = (0);
b::operator = (0);

したがって、オブジェクトによっては、test2 がパフォーマンスに大きな影響を与える可能性があります。また、初期化リストでオブジェクトを初期化することにより、コンストラクターに入ったときに変数にデータがあることが保証されます。初期化子リストの 1 つの「欠点」は、初期化子リストの順序ではなく、変数が宣言された順序で実行されることです。そのため、初期化子リストを使用したくない場合があります。

于 2013-03-28T11:49:09.253 に答える