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();}

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

Void constructor for Domastic_animal

Multiple constructor for Cat

Void constructor for Domastic_animal

Void constructor for Сat

Void constructor for Tomcat

Multiple constructor for Kitten.

The Cat size

The size=60

The Kitten size

The size=25

Друзі

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

Дружні класи

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

class Aclass{

private:

double value;

public:

Aclass() {v=3.14159;}};

та клас

class Bclass{

private:

Aclass anobject;

public:

Void ShowValue(void)

{cout<<anobject.value;}};

Поле value об'єкта anobject типу Aclass закрите в класі Bclass. Тому в наведеному прикладі у функції ShowValue виникне помилка. Уникнути її можна, якщо оголосити клас Bclass другом класу Aclass, використавши ключове слово friend:

class Aclass{

friend class Bclass;

private:

double value;

public:

Aclass(){value=3.14159;}};

Оголошення дружнього класу може міститись будь-де у протоколі опису класу (не обов'язково на початку формального опису після "{")). При оголошенні дружніх класів потрібно дотримуватись певних правил:

1. У класі мають бути перелічені всі його друзі.

2. Клас, у якому є закриті й захищені члени та дружній інший клас, надає можливість другу мати доступ до своєї закритої частини (за протоколом). Клас не може оголосити сам себе другом іншого класу.

3. Порядок оголошення класів і дружніх до них не має значення. Проте зазвичай дружні класи оголошуються після базових, щоб функції дружніх класів, які вбудовуються, могли звертатись до закритих і захищених частин вихідного класу.

4. Похідні від дружніх класів не є дружніми.

5. Синтаксично похідний клас може бути другом іншого. Результат – аналогічний.

Розглянемо приклад:

class One{

friend class Two;

private:

int x;

protected:

void doublex(void){x*=x;}

public:

One(){x=100;}

One(int n){x=n;}

};

class Two{

private:

One oneobject;

public:

void ShowValues(void);};


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



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