Шон Родительский разговор, Наследование является базовым классом зла, говорит, что полиморфизм не является свойством типа, а скорее является свойством как он используется. В качестве правила большого пальца не используйте наследование для реализации интерфейсов. Среди многих преимуществ этого является девиртуализация классов, которые имеют виртуальные функции только потому, что они реализуют интерфейс. Вот пример:
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*> для получения окончательного типа.)