コンストラクタ初期化リストはコロンで始まり、次にカンマ区切りのデータメンバリストが続きます。各データメンバの後には括弧で囲まれた初期化式が続きます。例:
class CExample {
public:
int a;
float b;
//构造函数初始化列表
CExample(): a(0),b(8.8)
{}
//构造函数内部赋值
CExample()
{
a=0;
b=8.8;
}
};
上記の例では、2つのコンストラクタの結果は同じです。上記のコンストラクタ(初期化リストを使用するコンストラクタ)はクラスのメンバを明示的に初期化します。一方、初期化リストを使用しないコンストラクタはクラスのメンバに代入するだけで、明示的な初期化は行いません。
初期化と代入は、組み込み型のメンバに対しては大きな違いはなく、上記のいずれのコンストラクタでも問題ありません。非組み込み型のメンバ変数の場合、2回の構築を避けるために、クラスコンストラクタ初期化リストの使用を推奨します。ただし、初期化リスト付きのコンストラクタを使用しなければならない場合もあります:
- 1. メンバ型がデフォルトコンストラクタを持たないクラス。明示的な初期化式が提供されない場合、コンパイラはメンバ型のデフォルトコンストラクタを暗黙的に使用します。クラスにデフォルトコンストラクタがない場合、コンパイラがデフォルトコンストラクタを使用しようとすると失敗します。
- 2.const メンバ或参照型のメンバ。const オブジェクトや参照型は初期化のみ可能で、代入はできないためです。
データメンバの初期化とデータメンバへの代入の意味は何ですか?違いは何ですか?
まずデータメンバを型ごとに分類し、ケースごとに説明します:
- 1.組み込みデータ型、複合型(ポインタ、参照)- メンバ初期化リストとコンストラクタ本体のどちらで行っても、パフォーマンスと結果は同じです
- 2.ユーザー定義型(クラス型)結果は同じですが、パフォーマンスには大きな違いがあります。クラス型のデータメンバオブジェクトは関数本体に入る前に構築が完了しているため、つまりメンバ初期化リストでオブジェクトの構築作業が行われ、コンストラクタが呼び出されます。関数本体に入った後は、構築済みのクラスオブジェクトへの代入が行われ、コピー代入演算子を呼び出して完了する必要があります(提供されていない場合は、コンパイラが提供するデフォルトのメンバ単位の代入動作が使用されます)。
注意点:
初期化リストのメンバ初期化順序:
C++ はクラスメンバを初期化する際、初期化リストに出現する順序ではなく、宣言された順序で初期化します。
class CMyClass {
CMyClass(int x, int y);
int m_x;
int m_y;
};
CMyClass::CMyClass(int x, int y) : m_y(y), m_x(m_y)
{
};
上記のコードはまず m_y=I が実行され、次に m_x=m_y が実行され、最終的に同じ値になると考えるかもしれません。しかしコンパイラは m_x を最初に初期化し、次に m_y を初期化します。なぜならそれらはこの順序で宣言されているからです。結果として m_x は予測できない値になります。これを回避する方法は2つあります。1つは、初期化したい順序でメンバを常に宣言することです。2つ目は、初期化リストを使用する場合は、常に宣言された順序でメンバを列挙することです。これにより混乱を解消できます。
原文アドレス:http://www.cnblogs.com/BlueTzar/articles/1223169.html