Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Невизначеність при множинному успадковуванні

Поиск

В певних ситуаціях можуть з’явитися певні проблеми, зв’язані з множинним успадковуванням. Далі ми розглянемо найзагальнішу. Припустімо, що в обох базових класах існують методи з однаковими іменами, а в похідному класі методу з таким іменем немає. Як в цьому випадку об’єкт похідного класу визначить, який з методів базового класу вибрати? Самого імені метода недостатньо, оскільки компілятор не зможе визначити, який з двох методі мається на увазі.

Ця ситуація проілюстрована в програмі 11.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;

 }

Програма 11.11

Проблема вирішується шляхом використання оператору дозволу, що визначає клас, в якому знаходиться метод. Таким чином, виклик

objC.A::show(); //правильний виклик

відправляє нас до версії методу show(), що належить класу А, а виклик

objC.B::show(); //правильний виклик

- до класу В.

В літературі (Б.Страуструп) це називається усуненням неоднозначністю.

Інший вид невизначеності з’являється, якщо ми створюємо похідний клас від двох базових класів, які, в свою чергу, є похідними одного класу. Це створює дерево успадковування в формі ромба. Така ситуація виникає в програмі 11.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;

 }

Програма 11.12

Класи В і С є похідними класу А, а клас D є похідним класів В і С. Труднощі виникають, коли об’єкт класу D намагається скористатися методом класу А. В програмі 11.12 об’єкт objD використовує метод func(). Однак класи В і С містять копії методу func(), успадковані від класу А. Компілятор на може вирішити, який метод використовувати, і повідомляє про помилку.

Існує багато варіацій цієї проблеми, тому ряд експертів радить уникати множинного успадковування.

 

Включення: класи в класах

Далі ми обговоримо включення, хоча воно й не має прямого стосунку до успадковування, механізми включення та успадковування є формами взаємовідносин між класами. Тому корисно буде порівняти їх.

Якщо клас В є похідним від класу А, то ми кажемо, що клас В є частково класом А, оскільки клас В має всі характеристики класу А, а також свої власні. Тому часто успадковування називають взаємовідносинами узагальнення.

Включення називають взаємовідносинами типу «має»: бібліотека «має» книжки, або «частина цілого»: книжка є частиною бібліотеки.

В ООП включення з’являється, якщо один об’єкт є атрибутом іншого об’єкту. Розглянемо випадок, коли об’єкт класу А є атрибутом класу В:

class A

{ };

class B

{ A objA;

}

 

Використаємо в програмі 11.9 включення замість успадковування. Класи manager та scientist є похідними класів employce та student. В новій програмі 11.13 ці класи міститимуть копії класів employce та student як атрибути.

Далі приведений лістінг програми 11.13.

 #include<iostream.h>

 #include<conio.h>

 #include<stdio.h>

 #include<bios.h>

 const int LEN=80;

 class student

 {private:

 char school[LEN];

 char degree[LEN];

 public:

 void getedu()

 {cout<<”School:”;

 cin>>school;

 cout<<”Degree:”;

 cin>>degree;

 }

 void putedu() const

 {cout<<”\nSchool=”<<school;

 cout<<”\nDegree=”<<degree<<endl;

 }

};

//////////////

class employce

 {private:

 char name[LEN];

 unsigned long number;

 public:

 void getdata()

 {cout <<”\nВведіть ПІП: “;cin>>name;

 cout <<”\nВведіть номер: “;cin>>number;

 }

 void putdata() const

 {cout<<”\nПІП=”<<name;

 cout<<”\nНомер=”<<number;

 }

 };

 //////////////

 class manager

 {private:

 char title[LEN];

 double dues;

 employce emp;

 student stu;

 public:

 void getdata()

 {emp.getdata();

 cout<<”\nПосада=”;cin>>title;

 cout<<”\nВнески=”;cin>>dues;

 stu.getedu();

 }

void putdata() const

 {emp.putdata();

 cout<<”\nПосада=”<<title;

 cout<<”\nВнески=”<<dues;

 stu.putedu();

 }

 };

///////////

class scientist

{private:

 int puts;

 employce emp;

 student stu;

 public:

 void getdata()

 { emp.getdata();

 cout<<”\nПублікації=”;cin>>puts;

 stu.getedu();

 }

 void putdata() const

 { emp.putdata();

 cout<<”\nПублікації=”<<puts;

 stu.putedu();

 }

 };

 ////////////

class laborer

 {private:

 employce emp;

 public:

 void getdata()

 {emp.getdata();}

 void putdata() const

 {emp.putdata();}

 };

 

////////////

 int main()

 {clrscr();

 manager m1;

 scientist s1,s2;

 laborer l1;

 cout<<endl;

 cout<<”\nManager 1:”;

 m1.getdata();

 

 cout<<”\nScientist 1:”;

 s1.getdata();

 

 cout<<”\nScientist 2:”;

 s2.getdata();

 

 cout<<”\nLaborer 1:”;

 l1.getdata();

 

 cout<<”Manager1\n”;

 m1.putdata();

 cout<<”Scientist1\n”;

 s1.putdata();

 cout<<”Scientist2\n”;

 s2.putdata();

 cout<<”Laborer1\n”;

 l1.putdata();

 bioskey(0);

 return 0;

 }

Програма 11.13

 

 

 

 

Класи manager та scientist містять члени об’єктного типу

employce emp;

student stu;

 



Поделиться:


Последнее изменение этой страницы: 2021-12-15; просмотров: 53; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.129.216.248 (0.006 с.)