Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Бичков - Основи сучасного програмування.doc
Скачиваний:
69
Добавлен:
07.03.2016
Размер:
2.67 Mб
Скачать

Int data;

public:

Void func(void){//тіло}};

class B:virtual public A

{//...};

class C:virtual public A

{//...};

class D:public B,public C

{//...};

class E

:virtual public A,

public D

{//...};

main()

{D d;

d.func();}

Бачимо, що в описі класів В i С присутнє слово virtual. При цьому ситуація змінюється таким чином: якщо клас А успадковується в кількох класах, то він не дублюватиметься. Розглянемо приклад:

class Company {

private:

char*name;

public:

company(const char*s){name=strdup(s);}

void Display(void){cout<<name<<'\n'}

};

class CocaCola:virtual public Company {

public:

CocaCola(void):Company("CocaCola") { }

};

class CocaColaUkr:virtual public Company,

Virtual public CocaCola {

public:

CocaColaUkr(void):Company("CocaColaUkr")

{//...}

};

У наведеному прикладі наявна помилка через повторне успадкування класів. Щоб її уникнути, потрібно використовувати віртуальні базові класи.

Допишемо до попереднього прикладу клас Pepsi:

class Pepsi:public Company{

public:

Pepsi():Company("Pepsi"){ }};

class Corporation:public CocaCola,

public Pepsi {//...};

Тут також буде помилка. Pepsi та CocaCola виводяться з company (хоч у CocaCola company є віртуальним). Щоб помилки не було, клас Company має бути оголошений віртуальним у Pepsi.

Опишемо тепер клас Corporation:

class Corporatin:public CocaCola,

public CocaColaUkr{ }

У цьому випадку помилка відсутня.

Виклик конструкторів

1. Віртуальні базові класи (ВБК) iнiцiалiзуються (викликається void-конструктор) перед будь-якими не ВБК у тому порядку, у якому вони зустрічаються в графі успадкування.

2. Якщо ВБК має хоча б один конструктор, то вiн повинен мати void-конструктор. Із похідного класу не можна прямо викликати не void-конструктор ВБК. Наприклад:

class Domastic_animal

{protected:

Int size;

public:

Domastic_animal(void)

{cout<<"\n void constructor for Domastic_animal\n";

size=0;}

Domastic_animal(int asize)

{

cout<<"\n multiple constructor for Domastic_animal\n";

size=asize;}

virtual void print(void)

{cout<<"The size="<<size<<'\n';}

};

class Cat:public virtual Domastic_animal

{public:

Cat(void)

{cout<<"\n void constructor for Cat\n";}

Cat(int aSize)

{cout<<"\n multiple constructor for Cat\n";

size=aSize;}

void print(void)

{cout<<"The Cat size\n";

Domastic_animal::print();

}

};

class Tomcat:public virtual Domastic_animal

{//аналогiчно Cat

public:

Tomcat(void)

{cout<<"\n void constructor for Tomcat\n";}

Tomcat(int aSize)

{cout<<"\n multiple constructor for Tomcat\n";

size=aSize;}

void print(void)

{cout<<"The Tomcat size\n";

Domastic_animal::print();

}

};

class Kitten:public Cat,public Tomcat

{public:

Kitten(int aSize)

{cout<<"\n multiple constructor for Kitten\n";

size=aSize;}

void print(void)

{//аналог функції в класі Cat};

cout<<"The Kitten size\n";

Domastic_animal::print();

}

};

main()

{Cat aCat(60);

Kitten aKitten(25);

Domastic_animal& myCat=aCat;

Domastic_animal & myKitten=aKitten;

myCat.print();

myKitten.print();}

Надрукується:

1. void constructor for Domastic_animal

2. multiple constructor for Cat

3. void constructor for Domastic_animal

4. void constructor for Сat

5. void constructor for Tomcat

6. multiple constructor for Kitten.

The Cat size

The size=60

The Kitten size

The size=25

7.11. Друзі

Інкапсуляція даних – одна з основних переваг ООП. Проте в С++ існує можливість обійти правила інкапсуляції, тобто доступу до різних частин опису класу.

7.11.1. Дружні класи

У класі можна оголосити інший клас дружнім. Один клас (у якому оголошується друг) дає можливість іншому (другу) мати доступ до всіх своїх закритих і захищених членів. Як відомо, відкриті члени завжди доступні. Тому немає необхідності оголошувати один клас другом іншого, щоб дати йому доступ до відкритих членів останнього. Механізм дружніх класів використовується у випадках, коли для двох класів, не пов'язаних "родинними" відношеннями, необхідний доступ до закритих і захищених секцій класів. Нехай оголошено клас

class Aclass{

private:

double value;

public:

Aclass() {v=3.14159;}};

та клас

class Bclass{

private:

Aclass anobject;

public: