История вопроса:
В ранних версиях C++ все члены класса должны были инициализироваться либо в списке инициализации конструктора, либо в теле конструктора. С появлением C++11 стала возможна инициализация нестатических членов класса прямо в месте их определения — это существенно улучшило читаемость и снизило вероятность ошибок с неинициализированными переменными.
Проблема:
Отсутствие инициализации по умолчанию приводило к неочевидному поведению для разработчиков, особенно при появлении новых конструкторов. Не было гарантии, что члены класса всегда инициализированы. Красота и новизна подхода — в уменьшении boilerplate-кода.
Решение:
Инлайн-инициализация задаёт значение по умолчанию для члена класса, если в списке инициализации конструктора он не был явно проинициализирован.
Пример кода:
class Widget { int value = 42; std::string name{"default"}; public: Widget() {} Widget(int v) : value(v) {} };
Ключевые особенности:
Будет ли использовано значение из инлайн-инициализации, если член задан в списке инициализации конструктора?
Нет, будет использовано значение из списка инициализации конструктора. Пример:
class Test { int a = 10; public: Test(int x) : a(x) {} }; Test t(42); // a == 42
Можно ли инлайн-инициализировать статические члены класса?
Нет, только нестатические. Статические члены класса инициализируются отдельно вне класса.
Можно ли использовать выражения для инициализации членов класса инлайн?
Для простых членов — да (например, вызов конструктора или литерал). Для сложных вычислений используйте функцию или инициализацию в конструкторе.
Команда добавила новый конструктор, но забыла инициализировать поле. Оно осталось с неинициализированным значением. Возникал краш при доступе к переменной.
Плюсы:
Минусы:
Применена инлайн-инициализация для всех полей класса. В новых конструкторах не приходилось явно прописывать инициализацию, снижено количество boilerplate-кода и ошибок.
Плюсы:
Минусы: