Второй вариант - не инициализация, а присвоение. С типами, которые имеют определяемые пользователем конструкторы по умолчанию, вторая опция будет вызывать конструктор по умолчанию, а затем вызывать оператор присваивания (независимо от того, определен он пользователем или нет) для присвоения значения.
Некоторые типы не могут быть инициализированы по умолчанию: если у вас есть атрибут без конструктора по умолчанию, содержатся ссылки (постоянные или нет) или атрибуты констант, они должны быть инициализированы в списке инициализаторов.
Массивы могут быть инициализированы значением в списке инициализации, но не в теле конструктора:
class X {
public:
X() : array() {} // value-initializes the array
// equivalent to:
// X() { for ( int i = 0; i < 10; ++i ) array[i]=0; }
private:
int array[10];
};
Для типов POD их можно инициализировать по значению в списке инициализации, но не в скобках:
class X {
public:
X() : pod() {} // value-initializes
// equivalent to (but easier to read and subtly faster as it avoids the copy):
// X() { pod = {}; }
private:
PODType pod;
};
Наконец, некоторые классы предлагают функциональность за счет использования конструкторов, которые будут более сложными (если они достижимы) после построения по умолчанию.
class X
{
public:
X() : v(10) {} // construct a vector of 10 default initialized integers
// equivalent to:
// X() { for ( int i = 0; i < 10; ++i ) v.push_back(0); }
private:
std::vector<int> v;
};
Наконец, всякий раз, когда они фактически эквивалентны, списки инициализации более идиоматичны в C ++.