ОП кажется смущенным.Вот что делать, это очень сложно, но работает.
Правило 1: Проектируйте абстракции.Если у вас есть отношение "is-A", вы должны использовать публичное виртуальное наследование.
struct Window { .. };
struct ListBox : virtual Window { .. };
Правило 2: Создавайте реализации, если вы реализуетеабстракция вы должны использовать виртуальное наследование.Вы можете свободно использовать наследование, чтобы сэкономить на дублировании.
class WindowImpl : virtual Window { .. };
class BasicListBoxImpl : virtual ListBox, public WindowImpl { .. };
class FancyListBoxImpl : public BasicListBoxImpl { };
Поэтому вы должны читать «виртуальный», что означает «isa», а другое наследование просто экономит на переписывающих методах.
Правило 3:Постарайтесь убедиться, что в конкретном типе есть только одна полезная функция: конструктор.Это иногда сложно, вам могут понадобиться некоторые настройки по умолчанию и некоторые методы set, чтобы возиться с вещами.Как только объект настроен , отбросьте реализацию .В идеале вы должны делать это при построении:
ListBox *p = new FancyListBoxImpl (.....);
Примечания: вы не собираетесь вызывать какие-либо абстрактные методы непосредственно или в реализации, поэтому частное наследование абстрактной базы просто прекрасно.Ваша задача исключительно определить эти методы, а не использовать их: это только для клиентов абстракций.Реализации виртуальных методов из баз также могут быть частными по той же причине.Наследование для повторного использования, вероятно, будет общедоступным, поскольку вы, возможно, захотите использовать эти методы в производном классе или вне его после конструирования, чтобы сконфигурировать ваш объект перед тем, как выбросить детали реализации.
Правило 4: существует стандартреализация многих абстракций, известная как Delegation , о которой вы говорили:
struct Abstract { virtual void method()=0; };
struct AbstractImpl_Delegate: virtual Abstract {
Abstract *p;
AbstractImpl_Delegate (Abstract *q) : p(q) {}
void method () { p->method(); }
};
Это симпатичная реализация, так как вам не нужно ничего знать об абстракции иликак это реализовать ...:)