В практике следует использовать только виртуальное наследование для определения интерфейсов, поскольку они, как правило, используются с множественным наследованием, чтобы гарантировать, что только один вариант класса присутствует в производном классе. И чистые интерфейсы - самая безопасная форма множественного наследования. Конечно, если вы знаете, что делаете, вы можете использовать множественное наследование по своему усмотрению, но это может привести к хрупкому коду, если вы не будете осторожны.
Самый большой недостаток с виртуальным наследованием заключается в том, что их конструкторы принимают параметры. Если вам нужно передать параметры конструктору виртуального базового класса, вы вынудите все производные классы явно вызвать конструктор (они не могут полагаться на базовый класс, вызывающий конструктор).
Единственная причина, по которой я могу ясно указать, что данные в вашем виртуальном базовом классе могут потребовать параметры конструктора.
Редактировать Я сделал некоторые домашние работы после комментария Мартина, спасибо Марин. Первая строка это не совсем верно:
В практике вы должны использовать только виртуального наследования для определения интерфейсов, поскольку они, как правило, используются множественного наследования для обеспечения , что только одна версия класса присутствует в производном классе.
Виртуальное наследование не имеет значения, если базовый класс является чистым интерфейсом (за исключением немного разных ошибок компилятора, в vc8, если все методы не реализованы). Это только делает реальную разницу, если базовый класс имеет данные, в этом случае вы в конечном итоге с алмазом, а не U формы
Non virtual virtual
A A A
| | / \
B C B C
\ / \ /
D D
В виртуальном случае B и C разделяют один и тот же экземпляр А.
Однако я все еще согласен со всем остальным в том, что чистые интерфейсы являются самой безопасной формой множественного наследования, даже если они не требуют виртуального наследования. И тот факт, что параметры конструктора и виртуальное наследование - это боль.
Не могли бы вы предоставить ссылку или цитату для консультации? см. большую точку в маркировке базового класса virtual, если у него нет данных, поскольку наиболее распространенной целью виртуального наследования является предотвращение дублирования членов базового класса. Например, в стандартных библиотеках ios_base имеет члены данных и являетсявиртуальный базовый класс (через ios) как istream, так и ostream. Поэтому я почти (но не совсем) говорю наоборот: если у вас будет виртуальный базовый класс, тогда он должен иметь членов данных или наследовать практически. –