Поняття про конструктори

Розглянемо описаний вище клас Timer. Оголосимо екземпляр класу v:

Timer v;

За такого оголошення відбувається лише виділення пам'яті для відповідного екземпляра класу. Програміст повинен сам подбати про ініціалізацію полів. Якщо уявити наявність кількох класів, що мають складну структуру, велику кількість полів даних, то задача правильної ініціалізації полів стає досить громіздкою й помилконебезпечною, адже у такому випадку необхідно тримати у пам'яті всю структуру класів. У деяких випадках при створенні об'єкта необхідне й виділення пам'яті. У зв'язку з цим у С++ введені функції-члени, що мають особливий синтаксис, призначення та назву. Вони є конструкторами та служать для ініціалізації полів даних, виділення пам'яті, якщо це необхідно, і виконання інших дій, які можуть бути потрібними при створенні екземпляра об'єкта.

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

clas TT {

private:

long dt;

char*dts;

publiс:

TT(int,int);

};

TT::TT(int a,int n)

{dt=a;

dts=(char*)malloc(n*sizeof(char));}

Main()

{

TT t2(1,15);

//...}

При оголошенні TT t2(1,15); одразу викликається конструктор класу, який ініціалізує поле dt і виділяє пам'ять. Умовою його виклику є відповідність параметрів, указаних у дужках, до сигнатури конструктора. Якщо в нашому прикладі оголосити змінну t2 як TT t2(1,1); то буде видане повідомлення про помилку. Адже конструктора з відповідною сигнатурою не існує.

У класах може бути оголошено кілька конструкторів за правилами перевантаження функцій, допускається використання параметрів за умовчанням. Специфічну роль відіграють конструктори, які мають порожній список параметрів. Вони називаються конструкторами за умовчанням. Якщо такий конструктор у класі є, то він завжди автоматично викликається при входженні екземпляра класу в область видимості. Наприклад:

class TT {

private:

long dt;

char*dts;

publiс:

TT();};

TT::TT(void)

{

dt=0;

dts=(char*)malloc(10*sizeof(char));}

Main()

{

TT v;

//....}

У момент оголошення змінної-екземпляра класу v відбувається виклик конструктора за умовчанням. Розглянемо ще один приклад. Опишемо клас

Class example

{

public:

int i;

example(int i){i=_i;}

};

і визначимо екземпляр класу: example a;

Виникає помилка. Адже в класі example немає void -конструктора. У такій ситуації необхідно визначити цей конструктор, хоча б з формально порожнім тілом:

Class example

{

public:

int i;

example(int i){i=_i;}

example(){}

};

Зазначимо, що відповідні конструктори класів викликаються й у ситуаціях, коли необхідне неявне перетворення типів.

Якщо конструктор відсутній, то об'єкт можна iнiцiалiзувати шляхом присвоєння йому об'єкта цього самого класу:

Timer today;

...

Timer d=today;

При цьому відбувається побітове чи почленне рекурсивне копіювання. Слід обережно працювати з класами, які мають конструктори, оскільки при присвоюванні екземплярів таких класів можуть виникати помилкові ситуації. Розглянемо приклад:

Class IntArray

{private:

int*data;

unsigned size;

public:

IntArray(void);

IntArray(unsigned mySize);

void put(unsigned index, int value);

int get(unsigned index);};


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



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