Да, использование функции (метод статического класса или обычной функции), которая принимает foo в качестве параметра и возвращает строку, является хорошим решением. Вы можете вызвать эту же функцию из Derived :: bar, чтобы предотвратить дублирование кода. Итак, ваш конструктор будет выглядеть так:
Derived(int f) : Base(stringof(f)), foo(f) {}
Я помещаю вызов конструктора Base первым в списке, чтобы подчеркнуть порядок, в котором происходят инициализации. Упорядочение списка инициализаторов не имеет никакого эффекта, поскольку все члены класса инициализируются в том порядке, в котором они объявлены в теле класса.
Это очень чистый, функциональный подход к проблеме. Однако, если вы все еще хотите взвесить альтернативы, рассмотрите возможность использования состав вместо наследования для отношений между производными и базовыми классами:
class Base {
public:
Base(string S) { ... }
void bat() { ... }
};
class Derived {
Base *base;
int foo;
public:
Derived(int f) : base(NULL), foo(f) {
base = new Base(bar());
}
~Derived() {
delete base;
}
string bar() {
return stringof(foo); // actually, something more complex
}
void bat() {
base->bat();
}
};
Вам нужно будет рассмотреть плюсы и минусы для вашей конкретной ситуации. С Derived, имеющим ссылку на Base, вы получаете больший контроль над порядком инициализации.