Рассмотрим следующую иерархию виртуального наследования
#include <string>
#include <iostream>
struct base
{
base() = default;
base( std::string const& s ) : s_(s) {}
std::string print() { return s_; }
private:
std::string s_;
};
struct derived : virtual base
{
derived( std::string const& s ) : base( "cool formatting: " + s ) {}
};
struct more_derived : virtual derived
{
more_derived( std::string const& s ) : derived( "even cooler formatting: " + s ) {}
};
int main()
{
std::cout << more_derived( "foo" ).print() << std::endl;
}
Желаемый результат:
cool formatting: even cooler formatting: foo
Код ничего не печатает, потому что more_derived
явно не вызывает base
конструктор, который принимает строку, и поэтому по умолчанию base
конструктор называется. Кроме того, из-за virtual
наследование derived
инициализация base
игнорируется
Как я могу получить желаемый результат при сохранении виртуального наследования и без необходимости явного вызова каждого конструктора базового класса?
РЕДАКТИРОВАТЬ:
Я понимаю, что то, что я прошу, невозможно, используя вызовы конструктора вниз по иерархии наследования из-за виртуального наследования. Я надеялся, что кто-нибудь сможет предложить альтернативный метод, который даст желаемый результат при построении most_derived
,
Вы просите о двух противоречивых целях. С одной стороны, вы хотите сохранить виртуальное наследование (оно вам действительно нужно?), А с другой стороны, вы хотите, чтобы конструктор не вызывался из самого производного типа напрямую.
Вы не можете получить оба, так что выбирайте один. Вы можете, конечно, передать желательно Строка из самого производного типа, но я предполагаю, что точка не фактическое значение, а тот факт, что значение создается снизу вверх …
Других решений пока нет …