2011-01-07 4 views
1

Просто простой вопрос о C++ кодирования стиля,класс список инициализации

, например, все переменные-члены класса будет называться с конструктором по умолчанию в списке инициализации, если мы ничего не делаем. B будет вызываться конструктор по умолчанию B, а значение будет установлено в 0, int();

class A 
{ 
    A(); 
private: 
    B b; 
    int value; 
} 

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

A :: A(): b(), value() {}

+0

Как вы имеете в виду? – Eilidh

+0

Всегда ли полезно печатать A :: A() {}, даже если оно пустое? – Eilidh

+0

хорошо, если вы не пишете: b(), value(), компилятор сделает это за вас, так что это не нужно и используйте только список инициализации, когда у вас есть аргумент для указания конструктора или когда вы хотите установить, например, int для значения, которое не равно – hidayat

ответ

2

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

Однако, int не будет инициализирован, если вы не сделаете это, что является серьезной причиной для написания конструктора.

+0

(+1) Подтвердите. Изменение порядка атрибутов внутри класса приводит также к рефакторингу списка, представляющему порядок инициализации. –

+0

В большинстве случаев я согласен. Но если класс содержит члены POD, я бы добавил явный конструктор, чтобы убедиться, что объект находится в определенном состоянии после построения. Если класс действительно просто мешок объекта (например, выше), в этом случае я бы сделал его структурой, чтобы отразить этот факт. –

+0

@ Raphael B .: Большинство компиляторов предупредит вас об этом (и, поскольку я всегда компилирую с предупреждениями, которые рассматриваются как ошибки), таким образом, вы не можете пропустить это изменение. –

1

По умолчанию переменные int не инициализируются значением - вы должны сделать это самостоятельно.

Поэтому, когда вы не устанавливаете значение переменной «значение» для некоторого значения в конструкторе, оно остается неинициализированным.

1

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

4

Вы касаетесь одного из липких углов C++.

Инициализация значений POD в объектах является липкой и зависит от нескольких вещей.
Даже я не уверен, что могу правильно исправить все правила, но я считаю, что @Steve Jessop однажды написал статью об этом здесь (хотя я могу найти ее сейчас).

Но некоторые примеры:

Этот класс всегда будет инициализирован б == ложь и значение = 0.

class A 
{ 
    A() : b(), value() {} 
    B b; 
    int value; 
}; 

Без явного конструктора с по умолчанию он является более сложным:
Здесь компилятор сгенерирует для вас конструктор по умолчанию. Но как работает компилятор, созданный по умолчанию конструктор, зависит от ситуации.Конструкторкомпилятором по умолчанию может сделать две различные формы инициализации и которая используется, зависит от контекста:

  1. Нулевой Initialization (Все члены POD являются zero'ed вне)
  2. Значение инициализации (Все члены POD являются остается неопределенным)

Пример:

class B 
{ 
    B b; 
    int value; 
}; 

// Variables of static storage duration (notably globals) 
// Will be zero initialized and thus b == false and value = 0 

B global; // Initialized 

int main() 
{ 
    // Object of automatic storage duration or dynamic storage duration 
    // These will depend on how they are declared. 

    // Value Initialization (POD re-mains undefined) 
    B bo1;   // b/value undefined 
    B* bp1 = new B; // b.balue undefined 

    // Zero Initialization 
    B bo2 = B();  // b = false, value = 0 
    B* bp2 = new B(); // b = false, value = 0 

    // Note: The most obvious syntax for zero initializing a local object 
    //  does not work as it is actually interpreted as a forward 
    //  declaration of a function; 
    B bo3(); 
}