Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
+ООП_Навч_посібник.doc
Скачиваний:
7
Добавлен:
01.07.2025
Размер:
6.58 Mб
Скачать

13.3. Динамічна ініціалізація конструктора

У мові програмування C++ як локальні, так і глобальні змінні можна ініціалізувати у процесі виконання програми. Цей процес іноді називають динамічною ініціалізацією. Дотепер у більшості настанов ініціалізації, що були представлені у цьому навчальному посібнику, використовувалися константи. Проте одну і ту ж саму змінну можна також ініціалізувати у процесі виконання програми, використовуючи будь-який С++-вираз, дійсний на момент оголошення цієї змінної. Це означає, що змінну можна ініціалізувати за допомогою інших змінних і/або викликів функцій за умови, що у момент виконання настанови оголошення загальний вираз ініціалізації має дійсне значення. Наприклад, різні варіанти ініціалізації змінних абсолютно допускаються у мові програмування C++:

int n = strlen(str);

double arc = sin(theta);

float d = 1.02 * pm/deltax;

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

Згадаймо, що в першому прикладі коду програми таймера ми не отримали великої переваги від перевантаження конструктора timerClass(), оскільки всі об'єкти цього типу ініціалізувалися за допомогою констант, відомих під час компілювання програми. Але у випадках, коли об'єкт необхідно ініціалізувати у процесі виконання програми, можна отримати істотний виграш від наявності множини різних форматів ініціалізації. Це дає змогу програмісту вибрати з наявних конструкторів той, який найточніше відповідає поточному формату даних.

Наприклад, у версії програми таймера для створення двох об'єктів B_ob і C_ob, яку наведено нижче, використовується динамічна ініціалізація конструктора.

Код програми 13.5. Демонстрація динамічної ініціалізації конструктора

#include <vcl>

#include <iostream> // Для потокового введення-виведення

#include <conio> // Для консольного режиму роботи

#include <ctime> // Для використання системного часу і дати

using namespace std; // Використання стандартного простору імен

class timerClass { // Оголошення класового типу

int seconds;

public:

// Задавання секунд у вигляді рядка

timerClass(char *t) { seconds = atoi(t);}

// Задавання секунд у вигляді цілого числа

timerClass(int t) { seconds = t;}

// Час, що задається в хвилинах і секундах

timerClass(int xv, int sec) { seconds = xv*60 + sec;}

// Час, що задається в годинах, хвилинах і секундах

timerClass(int hod, int xv, int sec)

{ seconds = 60*(hod*60 + xv) + sec;}

void run_timer(); // Таймер відліку часу

};

void timerClass::run_timer()

{

clock_t t1;

t1 = clock();

while((clock()/CLOCKS_PER_SEC – t1/CLOCKS_PER_SEC)< seconds);

cout << "\a"; // Подання звукового сигналу

}

int main()

{

timerClass A_ob(10); // Створення об'єкта класу

A_ob.run_timer();

char strMas[80];

cout << "Введіть кількість секунд: "; cin >> strMas;

timerClass B_ob(strMas); // Динамічна ініціалізація конструктора

B_ob.run_timer();

int xv, sec;

cout << "Введіть хвилини і секунди: "; cin >> xv >> sec;

timerClass C_ob(xv, sec); // Динамічна ініціалізація конструктора

C_ob.run_timer();

int hod;

cout << "Введіть години, хвилини і секунди: ";

cin >> hod >> xv >> sec;

timerClass D_ob(hod, xv, sec);// Динамічна ініціалізація конструктора

D_ob.run_timer();

getch(); return 0;

}

Як бачимо, об'єкт A_ob створюється, використавши ініціалізацію цілочисельною константою. Проте основою для побудови об'єктів B_ob і C_ob слугує інформація, що вводиться користувачем. Оскільки для об'єкта B_ob користувач вводить рядок, то є сенс перевантажити конструктор timerClass() для прийняття рядкової змінної. Об'єкт C_ob також створюється у процесі виконання програми з використанням даних, які вводяться користувачем. Оскільки у цьому випадку час вводиться у вигляді хвилин і секунд, то для побудови об'єкта C_ob логічно використовувати формат конструктора, що приймає два цілочисельні аргументи. Аналогічно створюється об'єкт D_ob, для якого час вводиться у вигляді годин, хвилин і секунд, тобто використовується формат конструктора, що приймає три цілочисельних аргументи. Важко не погодитися з тим, що наявність декількох форматів ініціалізації конструктора позбавляє програміста від виконання додаткових перетворень під час ініціалізації членів-даних об'єктів.

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

Варто знати! Розробляючи перевантажені конструктори, необхідно визначитися у тому, які ситуації важливо передбачити, а які можна і не враховувати.