До стандарта C++11 при необходимости писать несколько конструкторов с разными параметрами приходилось дублировать код инициализации в каждом из них, поскольку не было возможности вызывать другой конструктор внутри конструкторов класса.
Невозможность использовать уже существующую логику инициализации в других конструкторах приводила к дублированию кода и ошибкам при изменении логики инициализации: обновив один конструктор, легко было забыть про остальные.
С выходом C++11 появился механизм "делегирующих конструкторов", позволяющий одному конструктору класса вызывать другой конструктор этого же класса через синтаксис списка инициализации.
Пример кода:
class Widget { public: Widget() : Widget(0, "default") {} Widget(int n) : Widget(n, "user") {} Widget(int n, std::string name) : size(n), label(name) {} private: int size; std::string label; };
Теперь вся общая логика сосредоточена в одном "главном" конструкторе, всё остальное делегирует вызов.
Ключевые особенности:
Можно ли делегировать вызов другому конструктору через вызов функции внутри тела конструктора?
Нет. Вызов конструктора другого конструктора возможен только через список инициализации, а не внутри тела конструктора. Если вызвать функцию из тела конструктора, члены объекта будут уже инициализированы.
Что будет, если создать "кольцо" делегирования между конструкторами?
Кольцевое делегирование (например, A делегирует B, а B — A) приводит к ошибке компиляции C++: бесконечной рекурсии между конструкторами быть не может.
Можно ли делегировать вызов конструктора базового класса с помощью делегирующего конструктора производного класса?
Нет. Делегирующие конструкторы работают только внутри одного класса. Для вызова базового конструктора используется отдельный синтаксис:
class Base { public: Base(int) {} }; class Derived : public Base { public: Derived() : Base(42) {} };
Три конструктора, каждый явно инициализирует поля, логика не синхронизирована — вносят изменение только в один конструктор, два других некорректны.
Плюсы:
Минусы:
Один главный конструктор, остальные делегируют ему, вся логика инициализации централизована.
Плюсы:
Минусы: