Это непростой вопрос, потому что любое обсуждение этого вопроса приведет к наследованию и композиции.
Для примера виртуального наследования, я буду держать свой шахматный пример
Chess_piece
attributes: pos_x, pos_y;
/\
_________________/ \___________________
/ \
Bishop Rook
methods: methods:
first_diagonal_move(length) horizontal_move(length)
second_diagonal_move(length) vertical_move(length)
\__________________ ___________________/
\ /
Queen
И Королева наследует от методов как ладьи и слона, но королева имеет атрибуты только одного куска, так здесь мы будем использовать виртуальное наследование C++.
Далее представьте, что мы строим композитную геометрическую фигуру, состоящую из одного круга и одной точки. Вот «наследство» график:
Point Point
attributes: pos_x, posy attributes: pos_x
| |
| |
Circle |
attribute: radius |
\___________ ________________/
\ /
Figure
Здесь фигура будет иметь два различных экземпляра точки, поэтому мы не будем использовать виртуальное наследование.
На самом деле это происходит потому, что во втором случае мы пытаемся использовать наследование, где правильный шаблон должен быть составным: фигура фактически содержит точку и круг. Этот вид не виртуального наследования приводит к сложным вопросам, таким как . Какова позиция фигуры?. По этой причине OO советует использовать правило composition over inheritance.
Но, как обсуждаются более подробно в вышеприведенной связанной странице, наследование имеет технические лакомства: производный класс имеет непосредственный доступ к его методам базовых классов, а в структуре композиции, вы должны явно реализующими их даже строить простая реализация пересылки. В некоторых случаях это приводит к большому количеству кода для кипячения пластин, и чем больше кода, тем выше стоимость тестов (или больше риска ошибок, если вы не ...)
TL/DR: множественное наследование по сам по себе является сложным шаблоном, который не допускается по этой причине на некоторых пост-языках C++, таких как Java. Не виртуальное множественное наследование, как правило, представляет собой намек на паттерн запаха, поскольку наследование использовалось там, где должна быть композиция. Но если вы знаете, почему вы его используете (избегая дублирования кода является приемлемой причиной), и вы его документируете, его можно использовать. В конце концов, это разрешено языком C++ ...
Почему вы могли бы убедить их, что это может быть полезно? ИМХО, это совсем не важно. Они почти никогда не видят этого на ЗЕМЛЕ. Даже пример Королевы не так правилен. – AhmadWabbi
«Королева наследует от епископа и ладьи», это не является хорошим примером отношения * is-a *. –
Я согласен с @AhmadWabbi, что это редкая конструкция; но студенты спросят, почему C++ поддерживает как виртуальное, так и не виртуальное наследование. – oz1cz