2012-04-05 5 views
4

Рассмотрим этот конструктор: Packet() : bits_(0), datalen_(0), next_(0) {}C++ конструктор Понимание

Обратите внимание, что bits_, datalen_ и next_ являются поля в классе пакетов определяется следующим образом:

u_char* bits_; 
u_int datalen_; 
Packet* next_; 

Что эта часть конструктора означает? bits_(0), datalen_(0), next_(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" 
}; 

Это предпочтительный способ инициализации элементов.

+0

Ya Я тоже догадывался - но я хотел узнать техническое название этого дела, чтобы я мог больше узнать об этом. Спасибо :) – vigs1990

+0

Списки инициализации. –

+0

@ Luchian Grigore Что такое двойная инициализация? – vigs1990

2

Он называется списком инициализаторов и инициализирует поля со значениями, указанными в скобках. Ниже будет достичь того же конечного эффекта:

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

Разница заключается в том, что в моем примере вы делаете назначение, поля уже будут построены их конструктор по умолчанию.

Для пользовательских типов без конструктора по умолчанию список инициализаторов является единственным способом, так как вам необходимо предоставить некоторые параметры конструктору.

+0

В его конкретном случае, да, но для пользовательских членов данных это совершенно другое, может потребоваться указать это. –

+0

@LuchianGrigore сделано. – jrok

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, но первый не будет