Реализация проекта множественного наследования

#c #multiple-inheritance

#c #множественное наследование

Вопрос:

У меня есть 3 класса, A , B , и C где B an A и C является an A .

Эти классы предназначены для сохранения истории, поэтому A предоставляют виртуальный метод, который производные классы могут создавать, чтобы получать уведомления, когда история должна быть заархивирована, вызывается void archive() .

Теперь внезапно возникает необходимость получить информацию из A , B , и C в одном классе, и я не уверен, что это лучший подход.

Я подумал о создании нового класса D , который наследует от B and C , и изменил их наследование virtual public A , чтобы избежать проблемы с бриллиантами и D::archive() просто вызвать B::archive() and C::archive() .

Это хороший подход? Или я должен перепроектировать 4 класса таким образом, чтобы я не использовал множественное наследование?

Комментарии:

1. Now suddenly there is a need to have the information from A, B, and C in a single class — это корень зла. Чего именно вы пытаетесь достичь?

2. Информация в B и C очень различна, и никогда не думали или не представляли себе необходимость во всех 3 классах информации. Но, конечно, пару лет спустя кому-то в голову пришла «крутая» идея, и интерфейс не работает, поэтому я пытаюсь найти наилучший подход к изменению этого.

3. Трудно рассуждать об этом абстрактно. В общем, вы можете рассматривать композицию как альтернативу наследованию, но это зависит от специфики. MI может быть хорошим, когда это уместно.

Ответ №1:

Ваш подход является стандартным. C имеет множественное наследование, и вы должны чувствовать себя свободно использовать его. Похоже, вы знаете, как это сделать правильно.

Комментарии:

1. Это облегчение слышать. Я стараюсь избегать множественного наследования, насколько это возможно, и потребовалось некоторое время, чтобы правильно понять этот подход, поэтому я хотел убедиться, что я ничего не пропустил, прежде чем изменять весь код.

2. Кстати, другие предложенные подходы тоже действительны, но я предполагаю, что вам нужна иерархия для полиморфизма, и вы не хотите менять все это только для этого. Начиная с нуля, вы можете вместо этого рассмотреть смешивание интерфейсов (и композицию для повторного использования кода), но то, что вы рассматриваете, тоже нормально.

Ответ №2:

Как насчет использования композиции вместо этого?
Например. class D делегирует классам B и C вместо наследования.
Композиция может достигать тех же результатов, а код намного проще (ИМХО)

Ответ №3:

Остерегайтесь цепочки вызовов, которые могут иметь возможные методы переопределения: если B::method вызовы A::method и C::method вызовы A::method , когда вы объединяете их в D, делая виртуальным, если D::method вызывает оба C::method и B::method , вас A::method вызывают дважды.

Когда база становится виртуальной, вы должны избегать таких повторных входов.

Ответ №4:

Вы могли бы иметь D, полученный из A, содержащий два члена B и C. D::archive вызовет B::archive и C::archive