Невизначеність при множинному успадковуванні
В певних ситуаціях можуть з’явитися певні проблеми, зв’язані з множинним успадковуванням. Далі ми розглянемо найзагальнішу. Припустімо, що в обох базових класах існують методи з однаковими іменами, а в похідному класі методу з таким іменем немає. Як в цьому випадку об’єкт похідного класу визначить, який з методів базового класу вибрати? Самого імені метода недостатньо, оскільки компілятор не зможе визначити, який з двох методі мається на увазі.
Ця ситуація проілюстрована в програмі 17.11.
#include<iostream.h>
#include<conio.h>
#include<stdio.h>
#include<bios.h>
////////////
class A
{public:
void show() {cout<<"Class A\n";}
};
//////////////
class B
{public:
void show(){cout<<"Class B\n";}
};
///////////
class C:public A,public B
{
};
int main()
{clrscr();
C objC;
// objC.show(); помилкова ситуація
objC.A::show(); //правильний виклик
objC.B::show(); //правильний виклик
bioskey(0);
return 0;
}
Програма 17.11
Проблема вирішується шляхом використання оператору дозволу, що визначає клас, в якому знаходиться метод. Таким чином, виклик
objC.A::show(); //правильний виклик
відправляє нас до версії методу show(), що належить класу А, а виклик
objC.B::show(); //правильний виклик
- до класу В.
В літературі (Б.Страуструп) це називається усуненням неоднозначністю.
Інший вид невизначеності з’являється, якщо ми створюємо похідний клас від двох базових класів, які, в свою чергу, є похідними одного класу. Це створює дерево успадковування в формі ромба. Така ситуація виникає в програмі 17.12
#include<iostream.h>
#include<conio.h>
#include<stdio.h>
#include<bios.h>
//////////
class A
{
public:
void func();
};
class B:public A
{ };
////////
class C:public A
{ };
/////////
class D:public B,public C
{};
//////////
int main()
{clrscr();
// ObjD.func(); помилковий виклик
bioskey(0);
return 0;
}
Програма 17.12
Класи В і С є похідними класу А, а клас D є похідним класів В і С. Труднощі виникають, коли об’єкт класу D намагається скористатися методом класу А. В програмі 17.12 об’єкт objD використовує метод func(). Однак класи В і С містять копії методу func(), успадковані від класу А. Компілятор на може вирішити, який метод використовувати, і повідомляє про помилку.
Існує багато варіацій цієї проблеми, тому ряд експертів радить уникати множинного успадковування.
Дата добавления: 2015-08-26; просмотров: 636;