Шон Родительский разговор, Наследование является базовым классом зла, говорит, что полиморфизм не является свойством типа, а скорее является свойством как он используется. В качестве правила большого пальца не используйте наследование для реализации интерфейсов. Среди многих преимуществ этого является девиртуализация классов, которые имеют виртуальные функции только потому, что они реализуют интерфейс. Вот пример:
class Drawable
{
public:
virtual void draw() = 0;
};
class DrawA : public Drawable
{
public:
void draw() override{//do something}
};
class UseDrawable
{
public:
void do(){mDraw->draw();}
Drawable* mDraw;
};
Здесь вместо UseDrawable
требуется mDraw
быть Drawable*
, вы можете использовать его класс стираемого типа, который может обертываться вокруг любого класса, реализующего элемент с именем draw
. Итак, что-то вроде boost::type_erasure::any
с соответствующим определением. Таким образом, DrawA
не нужно наследовать от Drawable
- полиморфизм был действительно UseDrawable
требованием и не действительно свойством DrawA
.
Я пытаюсь реорганизовать некоторый код, следуя этому принципу. У меня есть абстрактный класс ModelInterface
и два конкретных класса ModelA
и ModelB
, наследующие от ModelInterface
. Следуя совету Шона, имеет смысл не форсировать ModelA
и ModelB
в иерархию наследования, а просто использовать стирание типа в местах, где требуется класс, удовлетворяющий понятию, моделируемому ModelInterface
.
Теперь моя проблема в том, что большинство мест в моем коде, которые в настоящее время используют ModelInterface
, также делают это, создавая соответствующий объект на основе файла конфигурации времени исполнения. В настоящее время factory имеет new
соответствующий объект и возвращает ModelInterface*
. Если я реорганизую код для использования стираемой стили (скажем что-то вроде boost::type_erasure::any<implement ModelInterface>
) в этих местах в коде, как мне построить такие объекты во время выполнения? Будут ли ModelA
и ModelB
все еще нужны классы с поддержкой RTTI? Или я могу factory -строить и использовать их без RTTI-информации?
(С RTTI я могу иметь абстрактный класс, скажем FactoryConstructible
, и использовать dynamic_cast<void*>
для получения окончательного типа.)