Я пытаюсь использовать абстрактный базовый класс C ++ так же, как и интерфейс Java. Предположим, что у нас есть следующий интерфейс классы только с чистыми виртуальными функциями:
class Shape { virtual double area()=0; };
class Square : public Shape { virtual void setLength(double length)=0; };
class Rectangle : public Square { virtual void setWidth(double width)=0; };
и я пытаюсь реализовать Square и Rectangle следующим образом:
class SquareImpl : public Square { /*implementation*/ };
class RectangleImpl : public SquareImpl, Rectangle { /*implementation*/ };
Где RectangleImpl
наследует как SquareImpl
, так и Rectangle
повторно использовать, скажем, SquareImpl :: area ()
. Однако, когда я пытаюсь скомпилировать, возникают две проблемы: во-первых, все методы в SquareImpl
не наследуются должным образом, и мне приходится вручную переопределить RectangleImpl :: area ()
и RectangleImpl :: setLength ()
. Во-вторых, это все еще создает проблему с ромбами, заключающуюся в том, что Shape
является неоднозначным основанием для RectangleImpl
.
Я мог бы скомпилировать код, если бы фактически унаследовал Square
от ] Shape
, но я не думаю, что производительность будет увеличиваться с добавлением дополнительных производных интерфейсов. Также странно, что RectangleImpl
по-прежнему не наследует SquareImpl :: setLength ()
, хотя SquareImpl :: area ()
наследуется хорошо. (здесь не обращайте внимания на практичность)
Другое решение могло бы заключаться в том, чтобы сделать интерфейсы независимыми друг от друга, то есть сделать Square
не унаследованным от Shape
. Но из-за этого я потеряю доступ к методам в Shape
, если я определю функции, которые принимают указатель Square *
. Это также сделает невозможным static_cast между Shape
и Square
.
Итак, мой вопрос: есть ли какой-либо другой шаблон проектирования в C ++ для решения такого рода параллельного наследования между интерфейсными классами и классы реализации, не требующие виртуального наследования?
(отредактируйте пояснение: приведенный выше пример кода - это просто фиктивная иллюстрация параллельного наследования между интерфейсами и реализациями. Я понимаю, что есть более эффективные способы реализации фигур, но моя проблема не в том, как реализовать фигуры.)