C ++构造函数理解

时间:2012-04-05 11:13:27

标签: c++ constructor initialization initialization-list

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

请注意,bits_datalen_next_是类包中的字段,定义如下:

u_char* bits_;
u_int datalen_;
Packet* next_;

构造函数的这一部分是什么意思? bits_(0), datalen_(0), next_(0)

3 个答案:

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

不同之处在于,在我的示例中,您正在执行赋值,字段已经由其默认构造函数构造。

对于没有默认构造函数的用户定义类型,初始化列表是唯一的方法,因为您需要为构造函数提供一些参数。