Ответ 1
Нет, они не устарели, как в этой статье Ознакомьтесь с новыми форматами инициализации С++ 11 в разделе инициализации члена класса ( внимание мое):
Имейте в виду, что если один и тот же элемент данных имеет как инициализатор члена класса, так и mem-init в конструкторе, последний имеет приоритет. Фактически вы можете воспользоваться этим поведением, указав значение по умолчанию для члена в форме инициализатора члена класса, которое будет использоваться, если конструктор не имеет явного mem-init для этот участник. В противном случае конструктор mem-init вступит в силу, переопределив инициализатор члена класса. Этот метод полезен в классах с несколькими конструкторами
Таким образом, хотя в инициализации члена класса очень удобно, он не устраняет необходимость в списках инициализации, но обе функции работают вместе, чтобы дать вам хороший способ указать значения по умолчанию и переопределить их, когда это необходимо. Это похоже на то, как Bjarne Stroustrup видит это, он говорит:
Это экономит немного ввода, но реальные преимущества приходят в классы с несколькими конструкторами. Часто для всех конструкторов используется обычный инициализатор для члена:
и предоставляет пример элементов, которые имеют общий инициализатор:
class A {
public:
A(): a(7), b(5), hash_algorithm("MD5"), s("Constructor run") {}
A(int a_val) : a(a_val), b(5), hash_algorithm("MD5"), s("Constructor run") {}
A(D d) : a(7), b(g(d)), hash_algorithm("MD5"), s("Constructor run") {}
int a, b;
private:
HashingFunction hash_algorithm; // Cryptographic hash to be applied to all A instances
std::string s; // String indicating state in object lifecycle
};
и говорит:
Тот факт, что hash_algorithm и s каждый имеет один умолчаний, теряется в беспорядке кода и может легко стать проблемой во время обслуживания. Вместо этого мы можем исключить инициализацию членов данных:
class A {
public:
A(): a(7), b(5) {}
A(int a_val) : a(a_val), b(5) {}
A(D d) : a(7), b(g(d)) {}
int a, b;
private:
HashingFunction hash_algorithm{"MD5"}; // Cryptographic hash to be applied to all A instances
std::string s{"Constructor run"}; // String indicating state in object lifecycle
};
Примечание: недостаток в С++ 11
Существует один недостаток использования в инициализации члена класса в С++ 11, поскольку он делает класс неагрегатом, мы больше не можем использовать агрегатная инициализация, что может быть довольно неожиданным. Это не относится к С++ 14, где это ограничение было удалено. Подробнее см. В разделе Инициализация агрегатов С++ 11 для классов с нестационарными инициализаторами элементов.