初期化リストを使用する利点について私が知っていることは、組み込みではないクラスメンバーを初期化するときに効率が上がることです。例えば、
Fred::Fred() : x_(whatever) { }
よりも好ましい
Fred::Fred() { x_ = whatever; }
xがカスタムクラスのオブジェクトである場合。それ以外は、一貫性を保つために、このスタイルは組み込みタイプでも使用されます。
これを行うことの最も一般的な利点は、パフォーマンスの向上です。式がメンバー変数x_と同じタイプである場合、式の結果はx_内で直接構築されます—コンパイラーはオブジェクトの個別のコピーを作成しません。
他のスタイルでは、式は別の一時オブジェクトを作成し、この一時オブジェクトはx_オブジェクトの代入演算子に渡されます。次に、その一時オブジェクトは;で破棄されます。それは非効率的です。
質問
初期化リストを使用すると、次の例で効率が向上しますか。利益はないと思います。最初のバージョンは文字列のコピーコンストラクターを呼び出し、他のバージョンは文字列の代入演算子を呼び出します(一時的なものは作成されません)。それは正しいですか?
class MyClass
{
public:
MyClass(string n):name(n) { }
private:
string name;
};
class MyClass
{
public:
MyClass(string n)
{
name=n;
}
private:
string name;
};
2番目のバージョンは文字列のデフォルトのctorを呼び出し、次に文字列のコピー割り当て演算子を呼び出します-cのコピーctorを直接呼び出す最初のバージョンと比較して(マイナーな)効率の低下が確実に発生する可能性があります(たとえば、文字列の実装によっては、役に立たない割り当て-その後、いくつかの小さな構造のリリース)。なぜ常に正しい方法を使用しないのですか?-)
Constデータメンバーを初期化する唯一の方法は初期化リストにあると思います
例えば。ヘッダー内:
class C
{
C();
private:
const int x;
int y;
}
そして、cppファイル内:
C::C() :
x( 10 ),
y( 10 )
{
x = 20; // fails
y = 20;
}
これは、次のようなメンバーを初期化するための優れた方法です。
以下は、初期化子リストを使用する場合のシナリオです。
コピーコンストラクタと代入演算子には明確な違いがあることに注意してください。
したがって、2番目の例では、その時点までにname
を作成するための作業がすでに行われています。
name=n;
が達成された。
ただし、(特にこの単純な例では)実行される作業が非常に小さく(おそらくstring
オブジェクトの一部のデータメンバーをゼロにするだけ)、最適化されたビルドで作業が完全に最適化される可能性は十分にあります。ただし、可能な場合は常に初期化リストを使用することをお勧めします。
初期化リストを介して コンストラクター委任 を実行することもできます。