4

考虑这个构造函数:Packet() : bits_(0), datalen_(0), next_(0) {}

注意bits_,datalen_next_是 Packet 类中的字段,定义如下:

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;
    }
};

所以第二个会收到 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 回答