Мова Сі навчальний посібник - книга, сторінка 41

У порівнянні з класом complexl в новий клас complex, крім конструктора, додатково введені компонентні функції re () і im (), за допомогою яких можна отримувати доступ до даних об'єктів. Вони повертають посилання відповідно на речову та уявну частини того об'єкта, для якого вони будуть викликані.

Нагадаємо, що для конструктора не ставить тип значення. Існують особливості і в виклику конструктора. Без явної вказівки програміста конструктор завжди автоматично викликається при визначенні (створення) об'єкта класу. При цьому використовуються замовчувані значення параметрів конструктора. Наприклад, визначивши об'єкт її з неявним викликом конструктора

отримаємо при виклику СС. re () значення 1.0. Функція cc.im () поверне посилання на cc.imag, і цей елемент об'єкта cc матиме значення 0.0, заданий як замовчувана значення параметра конструктора.

Отже, "конструктор перетворює фрагмент пам'яті в об'єкт, для якого виконані правила системи типів" [2], тобто в об'єкт того типу, який передбачений визначенням класу.

Конструктор існує для будь-якого класу, причому він може бути створений без явних вказівок програміста. Таким чином, для класів goods і complexl існують автоматично створені конструктори.

За замовчуванням формуються конструктор без параметрів і конструктор копіювання виду Т :: T (const Т) де T - ім'я класу. наприклад,

Такий конструктор існує завжди. За замовчуванням конструктор копіювання створюється загальнодоступним. У класі може бути декілька конструкторів (перевантаження), але тільки один з замовчує значеннями параметрів.

Конструктор не можна викликати як звичайну компонентну функцію. Для явного виклику конструктора можна використовувати дві різні синтаксичні форми:

імя_ класу імя_об'екта (фактіческіе_параметри_конструктора);
ім'я_класу (фактіческіе_параметри_конструктора);

Перша форма допускається тільки при непорожньої списку фактичних параметрів. Вона передбачає виклик конструктора при визначенні нового об'єкта даного класу:

complex SS (10.3,0.22); // SS.real == 10.3;
// SS.imag == 0.22
complex ЇЇ (2.345); // ЕЕ.real == 2.345;
// за замовчуванням EE.imag == 0.0
complex DD (); // Помилка! Компілятор вирішить, що це
// прототип функції без параметрів,
// повертає значення типу complex

Друга форма явного виклику конструктора призводить до створення об'єкта, що не має імені. Створений таким викликом безіменний об'єкт може використовуватися в тих висловлюваннях, де допустимо використання об'єкта даного класу. наприклад:

Цим визначенням створюється об'єкт ZZ, якому присвоюється значення безіменного об'єкта (з елементами real == 4.0, imag == 5.0), створеного за рахунок явного виклику конструктора.

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

ім'я_класу (спісок_ параметрів):
спісок_ініціалізаторов_ компонентних даних <тело_конструктора>

Кожен ініціалізатор списку відноситься до конкретного компоненту і має вигляд:

імя_компонента_данних (вираз) Наприклад:
class AZ public:
AZ (int in, float en, char cn). ii (5),
її (ii * en + in), cc (cn) <>
>;
AZ A (2,3.0, 'd'); // Створюється іменований об'єкт А
// з компонентами А.ii == 5,
// А.ее == 17, А.cc == 'd'
AZ X = AZ (0,2.0, 'z'); // Створюється безіменний об'єкт, в
// якому ii == 5, її == 10,
// cc == 'z', і копіюється
// в об'єкт Х

Перераховані особливості конструкторів, угоди про статуси доступу компонентів і нове поняття "деструктор" ілюструє наступне визначення класу "символьний рядок":

//STROKA.CPP - файл з визначенням класу "символьний
// рядок "
#include // Для бібліотечних строкових функцій
#include
class stroka
char * ch; // Покажчик на текстовий рядок
int len; // Довжина текстового рядка
public: // Загальнодоступні функції:
// Конструктори об'єктів класу:
// Створює об'єкт як новий рядок:
stroka (int N = 80):
// Рядок не містить інформації:
lеn (0)
ch [0] = '\ 0';
> // Створює об'єкт по заданому рядку:
stroka (const char * arch)
ch = new char [len + 1];
strcpy (ch, arch);
>
int len_str (void) // Повертає посилання на довжину рядка

char * string (void) // Повертає покажчик на рядок

void display (void) // Друкує інформацію про рядку

імя_об'екта. імя_ елемента

Друга операція забезпечує звернення до компонентних даними об'єкта по заданому вказівником на об'єкт:

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

Саме тому, крім областей видимості "файл", "блок", "функція", в Сі ++ введена особлива область видимості "клас".

Щоб компонент класу був в єдиному екземплярі і не тиражувався при створенні кожного нового об'єкта класу, він повинен бути визначений в класі як статичний, тобто повинен мати атрибут static. Деякі можливості статичних компонентів вже були продемонстровані на прикладі класу "товари на складі магазину".

Статичні компоненти класу після ініціалізації можна використовувати в програмі ще до визначення об'єктів даного класу. Таку можливість для загальнодоступних даних надає кваліфіковане ім'я компонента. Коли визначено хоча б один об'єкт класу, до його статичним компонентам можна звертатися, як до звичайних компонентів, тобто за допомогою операцій вибору компонентів класу ( '.' і '->'). Тут виникає одне утруднення. На статичні дані класу поширюються правила статусу доступу. Якщо статичні дані мають статус private або protected. то до них ззовні можна звертатися через компонентні функції. При кожному виклику такої компонентної функції необхідно вказати ім'я деякого об'єкту. До моменту звернення до статичних даних класу об'єкти класу можуть бути або ще не визначені, або їх може бути кілька і кожен придатний для виклику компонентних функцій. Без імені об'єкта звичайну компонентну функцію викликати не можна відповідно до вимог синтаксису. Але який об'єкт вибрати для виклику, адже кожен статичний елемент класу єдиний в ньому? Хотілося б мати можливість обійтися без імені конкретного об'єкта при зверненні до статичних даних класу. Таку можливість забезпечують статичні компонентні функції.

Схожі статті