4

このコンストラクターについて考えてみましょう。Packet() : bits_(0), datalen_(0), next_(0) {}

bits_、およびは、次のように定義されたクラスPacketのフィールドであることにdatalen_注意next_してください。

u_char* bits_;
u_int datalen_;
Packet* next_;

コンストラクターのこの部分はどういう意味ですか?bits_(0), datalen_(0), next_(0)

4

3 に答える 3

6

これは初期化リストであり、指定された値に値を設定します。

Packet() : bits_(0), datalen_(0), next_(0)
{
    assert( bits_ == 0 );
    assert( datalen_ == 0);
    assert( next_ == 0);
}
//...
Packet()
{
    //bits_ , datalen_, next_ uninitialized here
}

一部のメンバー(constデフォルトのコンストラクターがないメンバーまたはユーザー定義のクラスメンバー)は、初期化子リストの外部で初期化できません。

class A
{
    const int x;
    A() { x = 0; }  //illegal
};

class A
{
    const int x;
    A() : x(0) { }  //legal
};

この手法を使用すると、二重初期化は発生しないことにも言及する価値があります。

class B
{
public:
   B() { cout << "default "; }
   B(int) { cout << "b"; }
};

class A
{
   B b;
   A() { b = B(1); }   // b is initialized twice - output "default b"
   A() : b(1) { }      // b initialized only once - output "b"
}; 

これは、メンバーを初期化するための好ましい方法です。

于 2012-04-05T11:14:50.963 に答える
3

これは、最初のbits_、次にdatalen_、最後にnext_が値0を受け取ることを意味します。つまり、次の2つのコードスニペットは完全に同等です。

Packet()
     : bits_(0)
     , datalen_0)
     , next_(0)
{
}

この:

Packet()
{
    bits_ = 0;
    datalen_ = 0;
    next_ = 0;
}

ただし、注意してください。初期化の順序は、メンバーの宣言の順序によって決まります。つまり、次のコードは期待どおりに機能しません。

struct Packet
{
    int first;
    int second;

    Packet()
        : second(0)
        , first(second)
    {
    }
};

これと同等になります:

struct Packet
{
    int first;
    int second;

    Packet()
    {
        first = second;
    second = 0;
    }
};

したがって、2番目は0を受け取りますが、最初は受け取りません

于 2012-04-05T11:23:09.133 に答える
2

これは初期化リストと呼ばれ、括弧内に指定された値でフィールドを初期化します。以下は同じ最終効果を達成します:

Packet()
{
    bits_ = nullptr;  // or 0 or NULL pre-C++11
    datalen_ = 0;
    next_ = nullptr;
}

違いは、割り当てを行っている私の例では、フィールドはデフォルトのコンストラクターによってすでに構築されているということです。

デフォルトのコンストラクターがないユーザー定義型の場合、コンストラクターにいくつかのパラメーターを指定する必要があるため、初期化子リストが唯一の方法です。

于 2012-04-05T11:18:42.657 に答える