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

За разлика от много други обектно-ориентирани езици за програмиране, C ++ позволява множествено наследяване.

Множественото наследяване позволява на детски клас да наследява от повече от един родителски клас.

В началото изглежда много полезна функция. Но един потребител трябва да се забравя няколко gotchas при изпълнение на тази функция.

В примерите по-долу ще разгледаме няколко сценария, за които човек трябва да внимава.

Ще започнем с прост пример за обяснение на тази концепция в C ++.

Резултатът от този код е както следва:

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

В горния пример имаме основен клас, наречен LivingThing . The Animalи класовете на влечугите наследяват от него. Само Животнотоclass отменя метода breathe(). Класът змия наследява от класовете животни и влечуги . Той отменя техните методи. В горния пример няма проблем. Нашият код работи добре.

Сега ще добавим малко сложност.

Какво ще стане, ако клас Reptile замени breathe()метода?

Класът Snake не би знаел кой breathe()метод да извика. Това е „Диамантеният проблем“.

Диамантен проблем

Вижте кода по-долу. Той е като кода в горния пример, с изключение на това, че сме заменили breathe()метода в класа Reptile .

Ако се опитате да компилирате програмата, тя няма. Ще се взирате в съобщение за грешка като това по-долу.

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

Грешката се дължи на „Диамантения проблем“ на множественото наследяване. Класът Snake не знае кой breathe()метод да извика.

В първия пример само класът Animal е заменилbreathe()метод. Класът на влечугите не беше. Следователно не беше много трудно за класа Snake да разбере кой breathe()метод да извика. И класът Snake в крайна сметка извика breathe()метода на класа Animal .

Във втория пример класът Snake наследява дваbreathe() метода. В breathe()метода на животните и влечуги клас. Тъй като не сме заменили breathe()метода в клас Snake , има неяснота.

C ++ има много мощни функции като множествено наследяване. Но не е необходимо да използваме всички функции, които предоставя.

Не предпочитам да използвам множествено наследяване и вместо това да използвам виртуално наследяване.

Виртуалното наследяване решава класическия „Диамантен проблем“. Той гарантира, че дъщерният клас получава само един екземпляр на общия основен клас.

С други думи, класът Snake ще има само един екземпляр от класа LivingThing . Най животни и влечуги класове споделят този случай.

Това решава грешката във времето на компилация, която получаваме по-рано. Класовете, получени от абстрактни класове, трябва да заменят чистите виртуални функции, дефинирани в основния клас.

Надявам се да ви е харесал този преглед на множественото наследяване и „диамантения проблем“.