Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lucik_op.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
2.88 Mб
Скачать

Множественное наследование

В языке С++ имеется возможность образовывать производный класс от нескольких базовых классов. Общая форма множественного наследования имеет вид:

class имя_произв_класса : имя_базового_кл 1,…,имя_базового_кл N

{ содержимое класса

};

Иерархическая структура, в которой производный класс наследует от несколько базовых классов, называется множественным наследованием. В этом случае производный класс, имея собственные компоненты, имеет доступ к protected- и public-компонентам базовых классов.

Конструкторы базовых классов при создании объекта производного класса вызываются в том порядке, в котором они указаны в списке при объявлении производного класса.

При применении множественного наследования возможно возникновение нескольких конфликтных ситуаций. Первая - конфликт имен методов или атрибутов нескольких базовых классов:

class A

{public: void fun(){}

};

class B

{public: void fun(){}

};

class C : public A, public B

{ };

main()

{ C *c=new C;

c->fun(); // error C::f' is ambiguous

return 0;

}

При таком вызове функции fun() компилятор не может определить, к какой из двух функций классов A и B выполняется обращение. Неоднозначность можно устранить, явно указав, какому из базовых классов принадлежит вызываемая функция:

c->A:: fun(); или c->B::fun();

Вторая проблема возникает при многократном включении некоторого базового класса:

#include "iostream.h"

#include "string.h"

class A // БАЗОВЫЙ класс I уровня

{ char naz[20]; // название фирмы

public:

A(char *NAZ) {strcmp(naz,NAZ);}

~A() {cout << "деструктор класса А" << endl;}

void a_prnt() {cout << naz << endl;}

};

class B1 : public A // ПРОИЗВОДНЫЙ класс (1 Базовый II уровня)

{ protected:

long tn;

int nom;

public:

B1(char *NAZ,long TN,int NOM): A(NAZ),tn(TN),nom(NOM) {};

~B1() {cout << "деструктор класса В1" << endl;}

void b1_prnt()

{ A::a_prnt();

cout << " таб. N " << tn <<" подразделение = " << nom <<endl;

}

};

class B2 : public A // ПРОИЗВОДНЫЙ класс (2 Базовый II уровня)

{ protected:

double zp;

public:

B2(char *NAZ,double ZP): A(NAZ),zp(ZP) {};

~B2(){cout << "деструктор класса В2" << endl;}

void b2_prnt()

{ A::a_prnt();

cout << " зар/плата = " << zp << endl;

}

};

class C : public B1, public B2 // ПРОИЗВОДНЫЙ класс ( III уровня)

{ char *fam;

public:

C(char *FAM,char *NAZ,long TN,int NOM,double ZP) :

B1(NAZ,TN,NOM), B2(NAZ,ZP)

{ fam = new char[strlen(FAM)+1]

strcpy(fam,FAM);

};

~C() {cout << "деструктор класса С" << endl;}

void c_prnt()

{ B1::b1_prnt();

B2::b2_prnt();

cout << " фамилия " << fam<<endl;

}

};

void main()

{ C cc("Иванов","мастра",1234,2,555.6),*pt=&cc;

// cc.a_prnt(); ошибка 'C::a_prnt' is ambiguous

// pt->a_prnt();

cc.b1_prnt();

pt->b1_prnt();

cc.b2_prnt();

pt->b2_prnt();

cc.c_prnt();

pt->c_prnt();

}

В приведенном примере производный класс С имеет по цепочке два одинаковых базовых класса А (A<-B1<-C и A<-B2<-C), для каждого базового класса А строится свой объект (рис. 3, 4). Таким образом, вызов функции

cc.a_prnt();

pt->a_prnt();

некорректен, так как неизвестно, какую из двух функций (какого из двух классов А) требуется вызвать.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]