47

初期化リストを使用する利点について私が知っていることは、組み込みではないクラスメンバーを初期化するときに効率が上がることです。例えば、

Fred::Fred() : x_(whatever) { }

よりも好ましい

Fred::Fred() { x_ = whatever; }

x がカスタム クラスのオブジェクトの場合。それ以外は、一貫性を保つために組み込み型でもこのスタイルが使用されます。

これを行うことの最も一般的な利点は、パフォーマンスの向上です。式whateverがメンバー変数x_と同じ型である場合、whatever式の結果はx_内で直接構築されます — コンパイラはオブジェクトの別のコピーを作成しません.

もう 1 つのスタイルでは、別の一時オブジェクトが作成され、この一時オブジェクトが x_ オブジェクトの代入演算子に渡されます。次に、その一時オブジェクトは ; で破棄されます。それは非効率的です。

質問
初期化リストを使用すると、次の例で効率が向上しますか。得はないと思います。最初のバージョンは文字列のコピー コンストラクターを呼び出し、もう一方のバージョンは文字列の代入演算子を呼び出します (作成される一時的なものはありません)。それは正しいですか?

class MyClass
{
public:
    MyClass(string n):name(n) { }
private:
    string name;
};

class MyClass
{
public:
    MyClass(string n)
    {
        name=n;
    }
private:
    string name;
};
4

5 に答える 5

36

2 番目のバージョンは、string のデフォルト ctor を呼び出し、次に string の copy-assignment operator を呼び出します。c の copy-ctor を直接呼び出す最初のバージョンと比較して、確実に (マイナーな) 効率の低下が生じる可能性があります (たとえば、string の実装によっては、いくつかの小さな構造の無駄な割り当てと解放)。常に正しい方法を使用しないのはなぜですか?-)

于 2009-10-21T06:03:52.510 に答える
18

constデータメンバーを初期化する唯一の方法は、初期化リストにあると思います

例えば。ヘッダーで:

class C
{
    C();
private:
    const int x;
    int y;
}

そして、cpp ファイル内:

C::C() :
    x( 10 ),
    y( 10 )
{
    x = 20; // fails
    y = 20;
}
于 2009-10-21T08:11:55.230 に答える
14

次のメンバーを初期化するのに最適な方法です。

  • 定数です
  • デフォルトのコンストラクターはありません (プライベートです)
于 2009-10-21T09:25:50.073 に答える
12

コピー コンストラクターと代入演算子には明確な違いがあることに注意してください。

  • コピー ctor は、初期化情報を取得する場所として他のインスタンスを使用して新しいオブジェクトを構築します。
  • 代入演算子は、すでに完全に構​​築されている既存のオブジェクトを変更します (デフォルトのコンストラクターを使用するだけであっても)。

nameしたがって、2番目の例では、作成するためにすでにいくつかの作業が行われています

 name=n;

が達成された。

ただし、(特にこの単純な例では) 実行される作業が無視できるほど小さく (おそらくstringオブジェクト内の一部のデータ メンバーをゼロにするだけ)、最適化されたビルドで作業が完全に最適化される可能性は十分にあります。しかし、可能な限り初期化子リストを使用することは依然として良い形式であると考えられています。

于 2009-10-21T06:23:28.943 に答える
2

初期化リストを介してコンストラクタ委任を実行することもできます。

于 2013-03-19T08:25:39.583 に答える