В первых версиях C++ члены класса инициализировались внутри конструктора через присваивание. Впоследствии появилась возможность инициализации членов класса до входа в тело конструктора с помощью списка инициализации, что критически важно для константных членов, ссылок и производительности.
Некоторые члены класса (например, const-поля или ссылки) не могут быть инициализированы присваиванием внутри тела конструктора — они должны быть заданы в момент создания. Кроме того, если использовать присваивание, сначала будет вызван default-конструктор, а потом присваивание (два действия), что может быть накладно для сложных объектов:
class Example { const int x; std::string str; public: Example(int val, const std::string& s) : x(val), str(s) {} };
Используйте initializer list, чтобы сразу инициализировать члены класса. Это особенно важно для const, ссылок, членовых классов без конструктора по умолчанию, а также для производительности при работе с STL-классами и большими структурами.
Пример кода:
class Point { const int x; int& y; public: Point(int val, int& ref) : x(val), y(ref) {} };
Ключевые особенности:
Можно ли изменить порядок инициализации членов класса через порядок в списке инициализации конструктора?
Нет! Члены всегда инициализируются в порядке их объявления в классе, а не по порядку в initializer list. Игнорирование этого правила приводит к ошибкам порядка инициализации.
Что произойдет, если член-ссылка не инициализирована в initializer list, а только в теле конструктора?
Ошибка компиляции! Ссылку, как и const-поля, можно проинициализировать только в initializer list — они должны получить значение до входа в тело конструктора.
После iнициализации const-члена в initializer list его можно изменить в теле конструктора?
Нет, константный член нельзя изменить после инициализации — попытка изменить такое поле приведет к ошибке компиляции.
В конструкторе член класса инициализируется внутри тела конструктора. Для сложных объектов тратятся ресурсы на вызов дефолтного конструктора, затем на присваивание, потом на разрушение временного объекта.
Плюсы:
Минусы:
Все члены сразу инициализируются в initializer list, нет лишних операций и проблем с immutable полями.
Плюсы:
Минусы: