Как сказали несколько человек, отвечающих, вы не можете отложить вызов конструктора базового класса, но Конрад дал хороший ответ , который вполне может решить вашу проблему. Однако у этого есть свои недостатки (например, когда вам нужно инициализировать несколько функций значениями, вычисления которых имеют промежуточные результаты), поэтому для простоты приведем еще один способ решения проблемы фиксированного порядка инициализации, используя , используя это.
Учитывая фиксированный порядок инициализации, если у вас есть контроль над производным классом (и как еще вы пришли бы к скрипке с одним из его ctors?), Вы можете проникнуть в частную базу, чтобы он собирался инициализироваться перед другой базой, которая затем может быть инициализирована с уже рассчитанными значениями частной базы:
class my_dirty_little_secret {
// friend class the_class;
public:
my_dirty_little_secret(const std::string& str)
{
// however that calculates x, y, and z from str I wouldn't know
}
int x;
std::string y;
float z;
};
class the_class : private my_dirty_little_secret // must be first, see ctor
, public the_other_base_class {
public:
the_class(const std::string str)
: my_dirty_little_secret(str)
, the_other_base_class(x, y, z)
{
}
// ...
};
Класс my_dirty_little_secret
является частной базой, поэтому пользователи the_class
не могут его использовать, все его содержимое также является частным, с явной дружбой, предоставляющей только the_class
доступ к нему. Однако, поскольку он указан первым в списке базовых классов, он будет надежно создан до the_other_base_class
, поэтому все, что он вычисляет, можно использовать для его инициализации.
Хороший комментарий в списке базовых классов, надеюсь, не позволит другим нарушить работу путем рефакторинга.