Розробка власного класу STRING

Курсовой проект - Компьютеры, программирование

Другие курсовые по предмету Компьютеры, программирование

?іх класів дерева, а ієрархія класів вироджується в безліч незвязаних обєктів.

Істотно, щоб у кожному із класів-братів перевизначалися функції, певні в загальному віртуальному базовому класі. У такий спосіб кожний із братів може одержати свій варіант операцій, відмінний від інших. Нехай у класі window є загальна функція уведення get_input ():

 

class window {

// головна інформація

virtual void draw ();

virtual void get_input ();

};

 

В одному з похідних класів можна використати цю функцію, не замислюючись про те, де вона визначена:

 

class window_w_banner: public virtual window {

// клас "вікно із заголовком"

void draw ();

void update_banner_text ();

};

void window_w_banner:: update_banner_text ()

{

// ...

get_input ();

// змінити текст заголовка

}

 

В іншому похідному класі функцію get_input () можна визначати, не замислюючись про те, хто її буде використати:

 

class window_w_menu: public virtual window {

// клас "вікно з меню"

// визначення, повязані з меню

void draw ();

void get_input (); // перевизначає window:: get_input ()

};

 

Всі ці визначення збираються разом у похідному класі наступного рівня:

 

class clock

: public virtual window,

public window_w_banner,

public window_w_menu

{

void draw ();

};

 

Контроль неоднозначності дозволяє переконатися, що в класах-братах визначені різні функції:

 

class window_w_input: public virtual window {

// ...

void draw ();

void get_input (); // перевизначає window:: get_input

};

class clock

: public virtual window,

public window_w_input,

public window_w_menu

{ // помилка: обидва класи window_w_input і

// window_w_menu перевизначають функцію

// window:: get_input

void draw ();

};

 

Транслятор виявляє подібну помилку, а усунути неоднозначність можна звичайним способом: ввести в класи window_w_input і window_w_menu функцію, що перевизначає "функції-порушника", і якимось чином усунути неоднозначність:

 

class window_w_input_and_menu

: public virtual window,

public window_w_input,

public window_w_menu

{

void draw ();

void get_input ();

};

 

У цьому класі window_w_input_and_menu:: get_input () буде перевизначати всі функції get_input ().

 

1.14.11 Контроль доступу

Член класу може бути приватним (private), захищеним (protected) або загальним (public):

Приватний член класу X можуть використати тільки функції-члени й друзі класу X.

Захищений член класу X можуть використати тільки функції-члени й друзі класу X, а так само функції-члени й друзі всіх похідних від X класів.

Загальний член можна використати в будь-якій функції.

Ці правила відповідають розподілу функцій, що звертаються до класу, на три види: функції, що реалізують клас (його друзі й члени), функції, що реалізують похідний клас (друзі й члени похідного класу) і всі інші функції.

Контроль доступу застосовується одноманітно до всіх імен. На контроль доступу не впливає, яку саме сутність позначає імя. Це означає, що частками можуть бути функції-члени, константи й т.д. нарівні із приватними членами, що представляють дані:

 

class X {

private:

enum { A, B };

void f (int);

int a;

};

void X:: f (int i)

{

if (i<A) f (i+B);

a++;

}

void g (X& x)

{

int i = X:: A; // помилка: X:: A приватний член

x. f (2); // помилка: X:: f приватний член

x. a++; // помилка: X:: a приватний член

}

 

1.14.12 Захищені члени

Дамо приклад захищених членів, повернувшись до класу window з попереднього розділу. Тут функції _draw () призначалися тільки для використання в похідних класах, оскільки надавали неповний набір можливостей, а тому не були достатньо зручні й надійні для загального застосування. Вони були як би будівельним матеріалом для більше розвинених функцій.

З іншого боку, функції draw () призначалися для загального застосування.

Це розходження можна виразити, розбивши інтерфейси класів window на дві частини - захищений інтерфейс і загальний інтерфейс:

 

class window {

public:

virtual void draw ();

// ...

protected:

void _draw ();

// інші функції, що служать будівельним матеріалом

private:

// подання класу

};

 

Така розбивка можна проводити й у похідних класах, таких, як window_w_border або window_w_menu.

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

От менш практичний, але більше докладний приклад:

 

class X {

// за замовчуванням приватна частина класу

int priv;

protected:

int prot;

public:

int publ;

void m ();

};

 

Для члена X:: m доступ до членів класу необмежений:

 

void X:: m ()

{

priv = 1; // нормально

prot = 2; // нормально

publ = 3; // нормально

}

 

Член похідного класу має доступ тільки до загальних і захищених членів:

 

class Y: public X {

void mderived ();

};

Y:: mderived ()

{

priv = 1; // помилка: priv приватний член

prot = 2; // нормально: prot захищений член, а

// mderived () член похідного класу Y

publ = 3; // нормально: publ загальний член

}

 

У глобальній функції доступні тільки загальні члени:

 

void f (Y* p)

{

p->priv = 1; // помилка: priv п