Розробка власного класу 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 п