Skip to main content

Что такое виртуальное наследование?

Виртуальное наследование - это тип наследования, при котором реализация суперкласса является неполной, а подкласс необходим для полного определения объекта. Этот тип наследования может использоваться в сочетании с одиночным и множественным наследованием, но чаще всего используется в множественном наследовании. Любой класс, который наследуется от виртуального базового класса, становится прямым подклассом этого базового класса. Виртуальный базовый класс может полагаться на подкласс для реализации всех своих методов, но это не является обязательным требованием.

C ++ является наиболее известным компьютерным языком для виртуального наследования. Чтобы объявить виртуальное наследование в C ++, используется ключевое слово «virtual». И суперкласс, и подкласс должны объявлять виртуальные методы с ключевым словом «virtual». Это говорит компилятору C ++, что суперкласс неполон, и он должен получить информацию из подкласса, чтобы завершить его. Использование подкласса для завершения суперкласса не означает, что подклассы перезаписывают друг друга, если они имеют один и тот же базовый класс, и вместо этого компилятор C ++ заботится о том, чтобы определить, какие части идут с каждым объектом.

Поскольку для виртуального наследования требуется виртуальный базовый класс, глобальные функции в C ++ не могут быть объявлены виртуальными. Этот тип наследования может использоваться только при соблюдении принципов объектно-ориентированного программирования (ООП). Причина этого заключается в том, что глобальные функции не связаны с конкретным классом и, как правило, сами по себе независимы. Без наследования суперкласса и подкласса не может произойти, поэтому глобальные функции и виртуальное наследование являются взаимоисключающими. Глобальные функции могут, теоретически, использоваться внутри виртуальных функций, но обратное может не всегда работать.

Виртуальное наследование используется для решения многих задач программирования, и одна из самых полезных - это разрешение неоднозначности. При множественном наследовании можно иметь базовый класс A, который имеет два подкласса, B и C, а затем класс D, который наследуется от обоих классов B и C. Этот шаблон обычно называют «алмазом смерти», потому что если классы A, B и C имеют реализации одного и того же метода, класс D не может определить, какую реализацию он должен использовать. Виртуальное наследование решает эту проблему, потому что реализация каждого класса остается отличной, и, следовательно, однозначной. Это различие обрабатывается специализированными внутренними объектами, называемыми виртуальными таблицами (vtables), которые отслеживают каждый тип объекта, но программисту не нужно явно манипулировать этими таблицами, поскольку они встроены в язык.