Множинне успадкування в C ++ та проблема з діамантами

На відміну від багатьох інших об'єктно-орієнтованих мов програмування, C ++ дозволяє множинне успадкування.

Множинне успадкування дозволяє дочірньому класу успадкувати більше ніж один батьківський клас.

На початку це здається дуже корисною функцією. Але користувач повинен пам’ятати про кілька помилок під час реалізації цієї функції.

У наведених нижче прикладах ми розглянемо кілька сценаріїв, про які слід пам’ятати.

Ми почнемо з простого прикладу, щоб пояснити цю концепцію на С ++.

Результат цього коду такий:

I'm breathing as a snake.I’m crawling as a snake.

У наведеному вище прикладі ми маємо базовий клас, який називається LivingThing . тварині класи рептилій успадковують від нього. Тільки Тваринаклас замінює метод breathe(). Клас Змія успадковується від класів Тварин та Рептилій . Це замінює їх методи. У наведеному вище прикладі немає проблем. Наш код працює добре.

Тепер ми додамо трохи складності.

Що робити, якщо клас Reptile замінює breathe()метод?

Клас Snake не знав би, який breathe()метод викликати. Це «Алмазна проблема».

Алмазна проблема

Подивіться на код нижче. Це як код у прикладі вище, за винятком того, що ми перевизначили breathe()метод у класі Reptile .

Якщо ви спробуєте скласти програму, вона не буде. Ви будете вдивлятися в повідомлення про помилку, як наведене нижче.

member ‘breathe’ found in multiple base classes of different types

Помилка пов’язана з “діамантовою проблемою” багаторазового успадкування. Клас Snake не знає, який breathe()метод викликати.

У першому прикладі лише клас Animal перевизначивbreathe()метод. Клас Рептилій не мав. Отже, для класу Змія не було дуже важко зрозуміти, який breathe()метод викликати. І в кінцевому підсумку клас Змія викликав breathe()метод класу Animal .

У другому прикладі клас Snake успадковує дваbreathe() методи. breathe()Метод тварин і рептилій класу. Оскільки ми не замінили breathe()метод у класі Snake , існує неоднозначність.

C ++ має безліч потужних функцій, таких як множинне успадкування. Але необов’язково використовувати всі функції, які він надає.

Я не вважаю за краще використовувати множинне успадкування і використовую віртуальне успадкування.

Віртуальна спадщина вирішує класичну “Алмазну проблему”. Це гарантує, що дочірній клас отримує лише один екземпляр загального базового класу.

Іншими словами, клас Snake матиме лише один екземпляр класу LivingThing . У тварин і рептилій класи поділяють цей екземпляр.

Це вирішує помилку часу компіляції, яку ми отримуємо раніше. Класи, похідні від абстрактних класів, повинні замінювати чисті віртуальні функції, визначені в базовому класі.

Сподіваюся, вам сподобався цей огляд багаторазового успадкування та "діамантова проблема".