100

このコンストラクタでコロン演算子 (":") は何をしますか? と同等MyClass(m_classID = -1, m_userdata = 0);ですか?

class MyClass {
public:

    MyClass() : m_classID(-1), m_userdata(0) { 
    }

    int m_classID;
    void *m_userdata;
};
4

9 に答える 9

109

これは初期化リストであり、コンストラクターの実装の一部です。

コンストラクターのシグネチャは次のとおりです。

MyClass();

これは、コンストラクターをパラメーターなしで呼び出すことができることを意味します。これにより、デフォルトのコンストラクター、つまり、書き込み時にデフォルトで呼び出されるコンストラクターになりますMyClass someObject;

その部分 を初期化リスト: m_classID(-1), m_userdata(0)と呼びます。これは、未定義のままにするのではなく、選択した値でオブジェクトの一部のフィールド (必要に応じてすべてのフィールド) を初期化する方法です。

初期化リストを実行した後、コンストラクター本体 (例ではたまたま空) が実行されます。その中でさらに多くの割り当てを行うことができますが、一度入力すると、すべてのフィールドがすでに初期化されています - ランダムな未指定の値、または初期化リストで選択した値のいずれかに。これは、コンストラクタ本体で行う代入は初期化ではなく、値の変更であることを意味します。

于 2009-08-13T15:26:45.613 に答える
48

初期化リストです。

コンストラクターの本体に入るまでに、すべてのフィールドが既に構築されています。デフォルトのコンストラクターがある場合、それらは既に呼び出されています。ここで、コンストラクターの本体でそれらに値を代入すると、コピー代入演算子が呼び出されます。これは、オブジェクトにリソース (メモリなど) があれば解放して再取得することを意味する場合があります。

したがって、int のようなプリミティブ型の場合、コンストラクターの本体でそれらを割り当てることに比べて利点はありません。コンストラクターを持つオブジェクトの場合、1 回ではなく 2 回のオブジェクトの初期化を回避できるため、パフォーマンスの最適化になります。

フィールドの 1 つが参照である場合は、オブジェクトの構築とコンストラクターの本体の間の短い時間であっても、参照が null になることはあり得ないため、初期化リストが必要です。次のコードでは、エラー C2758 が発生します: 'MyClass::member_' : コンストラクター ベース/メンバー初期化子リストで初期化する必要があります

class MyClass {
public :
    MyClass(std::string& arg) {
        member_ = arg;
    }
    std::string& member_;
};

唯一の正しい方法は次のとおりです。

class MyClass {
public :
    MyClass(std::string& arg) 
        : member_(arg) 
    {
    }
    std::string& member_;
};
于 2009-08-13T15:37:00.043 に答える
3

これは、オブジェクトのメンバー変数を初期化するためのイニシャライザ リストの開始を示します。

に関して:MyClass(m_classID = -1, m_userdata = 0);

これは、引数を取ることができるコンストラクターを宣言します (したがって、3 と 4 になるMyClassusing を作成できます)。コンストラクターに引数を渡さないと、イニシャライザー リストを持つバージョンに対して同等のオブジェクトが作成されます。MyClass m = MyClass(3, 4)m_classIDm_userdataMyClass

于 2009-08-13T15:25:24.740 に答える
2

これは、イニシャライザ リストの開始を通知します。

また、MyClass(m_classId=-1,m_userData=0) と同等ではありません。これは、デフォルト値を持つ 2 つのパラメーターを持つコンストラクターを定義しようとしています。ただし、値には型がなく、まったくコンパイルされません。

于 2009-08-13T15:27:07.437 に答える
1

初期化リストです。あなたの例では、むしろ次のようなものです(このようなもの-すべての場合で同等であることを意味するわけではありません):


class MyClass {

public:

    MyClass(){
         m_classID = -1;
         m_userdata = 0;
    }

    int m_classID;
    void *m_userdata;

};
于 2009-08-13T15:26:44.257 に答える
1

これはメンバー初期化リストと呼ばれます。スーパークラスのコンストラクターを呼び出し、作成時にメンバー変数に初期値を与えるために使用されます。

この場合、m_classID-1 とm_userDataNULL に初期化されます。

後者は最初にメンバー変数を作成し、次にそれらに割り当てるため、コンストラクターの本体での割り当てとはまったく同じではありません。初期化では、作成時に初期値が提供されるため、複雑なオブジェクトの場合はより効率的になります。

于 2009-08-13T15:27:32.523 に答える
1

正確にはオペレーターではありません。これは、コンストラクターの構文の一部です。

それが言っているのは、それに続くのはメンバー変数とその初期値のリストになるということです。

定数メンバーは、この方法で初期化する必要があります。単一の式で実行できる限り、非定数もここで初期化できます。メンバーを初期化するのにそれ以上のコードが必要な場合は、実際のコードを {} の間に挿入する必要があります。

多くの人は、ほとんどすべてのコンストラクタ コードを初期化リストに入れることを好みます。私には、初期化子のいくつかの画面を持つクラスを定期的に作成し、コンストラクター コードに "{}" を配置する同僚が 1 人います。

于 2009-08-13T15:28:00.977 に答える
1

オブジェクトの構築中にメンバー変数を設定する初期化リストの開始です。あなたの例「MyClass(m_classID = -1, m_userdata = 0);」正しいコンストラクターを定義しておらず、とにかくパラメーターリストのメンバー変数にアクセスできないため、不可能です...次のようなものがあります。

MyClass( int classId = -1, void* userData = 0 ) : m_classID(classId), m_userdata(userData) {}

初期化子リストは、次のものよりも優れていると見なされます。

MyClass( int classId = -1, void* userData = 0 ) {
    m_classID = classId;
    m_userdata = userData;
}

詳細については、Google。

于 2009-08-13T15:29:19.493 に答える
0

この場合: はい、プリミティブ型のみが関係するため、 ist は同等です。

メンバーがクラス (構造体) の場合は、初期化リストを優先する必要があります。これは、それ以外の場合、オブジェクトがデフォルトで構築されてから割り当てられるためです。

于 2009-08-13T15:25:46.893 に答える