Досі ми розглядали просте успадкування, коли похідний клас утворювався з одного базового. У С++ похідний клас можна утворювати з кількох базових. Множинне успадкування відрізняється лише тим, що похідний клас успадковує всі властивості базових.
Нехай А, 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 у звичайному успадкуванні після двокрапки при визначенні конструктора. Конструктори в похідному класі викликаються в тому порядку, у якому оголошені базові класи. Навіть якщо в конструкторі похідного класу вказати послідовність виклику іншою, відмінною від порядку наступності базових класів, то це не вплине на результат.
|
|