考虑这个构造函数:Packet() : bits_(0), datalen_(0), next_(0) {}
请注意,bits_
,datalen_
和next_
是类包中的字段,定义如下:
u_char* bits_;
u_int datalen_;
Packet* next_;
构造函数的这一部分是什么意思? bits_(0), datalen_(0), next_(0)
答案 0 :(得分: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"
};
这是初始化成员的优先方式。
答案 1 :(得分:3)
这意味着首先位_ ,然后 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,但第一将不会
答案 2 :(得分:2)
它被称为初始化列表,它使用括号中指定的值初始化字段。以下将达到相同的最终效果:
Packet()
{
bits_ = nullptr; // or 0 or NULL pre-C++11
datalen_ = 0;
next_ = nullptr;
}
不同之处在于,在我的示例中,您正在执行赋值,字段已经由其默认构造函数构造。
对于没有默认构造函数的用户定义类型,初始化列表是唯一的方法,因为您需要为构造函数提供一些参数。