Множинне успадкування

Досі ми розглядали просте успадкування, коли похідний клас утворювався з одного базового. У С++ похідний клас можна утворювати з кількох базових. Множинне успадкування відрізняється лише тим, що похідний клас успадковує всі властивості базових.

Нехай А, B, С – деякі класи. Тоді похідний від них клас оголошується так:

Class D:public A,public B,public C

{//...};

Аналогічно, як i в простому успадкуванні, відсутність специфікатора доступу за умовчанням інтерпретується закритим специфікатором (private). Наприклад:

Class Coord

{protected:

int x,y;

public:

Coord(int_x=0,int_y=0);

void SetLoc(int_x,int_y);};

Coord::Coord(int_x,int_y)

{SetColor(_x,_y);};

Void Coord::SetLoc(int_x,int_y)

{x=_x;

y=_y;}

Class Message

{protected:

char msg[MAX_LEN];

public:

void SetMsg(char*_msg)

{strcpy(msg,_msg);}

};

Class MessageXY:public Coord,public Message

{public:

void show();};

Void Message XY::show()

{goto(x,y);

printf(msg); }

Int main()

{MessageXY greeting;

greeting.SetLoc(10,10);

greeting.SetMsg("Hellow");

greeting.Show();

return 0;};

Із прикладу бачимо, як із двох класів – Coord та Message – утворюється третій – MessageXY. Він успадковує всі поля даних і функції-члени базових класів. Це дозволяє у функції Message XY::show() використовувати поля x, y та msg.

При конфлікті імен (напр., у двох базових класах оголошена функція-член з одним і тим самим іменем) необхідно використовувати операцію розширення області видимості для визначення необхідного нам члена класу.

Припустимо, що у двох базових класах оголошена функція з одним і тим самим ім'ям (func):

Class A

{protected:

int data;

public:

void func(void){}

};

class B{

public:

void func(void){};

Class C:public A,public B

{public:

int data;

};

Int main(void)

{C c;

C.func() //помилка на етапi компiляцiї

с.data=10;

return 0;}

Вихiд із даної ситуацiї один – розширення областi видимості, тобто виклик функцiї func має здiйснюватися таким чином (у main):

Int main(void)

{C c;

с.A::func();

с.B::func();

с.data=10;

return 0;}

Можна описати ще одну функцію, у якій указати, яку з конфліктуючих функцій і коли викликати.

У класі, виведеному із кількох базових, може виникнути необхідність у виклику конструкторів цих класів. Якщо класи А, В, С мають конструктори за умовчанням, то в похідному класі D їх можна викликати таким чином:

class D:public A,public B,public C{

public:

D():A(),B(),C(){ }//...};

Або ж конструктор можна оголосити так:

class D:public A,public B,public C{

public:

D();//...};

і реалізувати його за межами формального опису класу:

D::D():A(),B(),C(){ }

У базових класах можуть бути конструктори з параметрами. Вони викликаються аналогічно, як i у звичайному успадкуванні після двокрапки при визначенні конструктора. Конструктори в похідному класі викликаються в тому порядку, у якому оголошені базові класи. Навіть якщо в конструкторі похідного класу вказати послідовність виклику іншою, відмінною від порядку наступності базових класів, то це не вплине на результат.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: