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

Int mainO

{

myClass 0bjA(4); cout« ObjA.PutO; getchO; return 0;

}

У цьому коді програми конструктор класу myClass приймає один параметр. Зверніть увагу на те, який оголошено об'єкт ObjA у функції main(). Значення 4, що задається у круглих дужках після імені ObjA, є аргументом, який передається пара­метру х конструктора myClass(), а параметр х, своєю чергою, використовується для ініціалізації члена а. Саме таким способом ми ініціалізуємо члени класу, як це бу­ло показано на початку цього навчального посібника. Проте існує і альтернатив­ний варіант ініціалізації. Наприклад, у процесі виконання такої настанови член класу а також набуде значення 4.

myClass ObjA = 4; // Цей формат ініціалізації перетвориться у формат myClass(4).

Як зазначено у коментарі, цей формат ініціалізації автоматично перетворить­ся у виклик конструктора класу myClass, а число 4 використано як аргумент. Інши­ми словами, попередня настанова обробляється компілятором так, як вона була записана:

myClass ObjA(4);

У загальному випадку завжди, якщо у Вас є конструктор, який приймає тіль­ки один аргумент, то для ініціалізації змінних об'єкта можна використовувати будь-який з форматів: або ObjA(x), або ObjA = х. Йдеться про те, що при створенні конструктора класу з одним аргументом Ви опосередковано створите перетворен­ня з типу аргумента в тип цього класу.

Для створення "неконвертованого" конструктора використовується специфікатор explicit.

Якщо програмісту не потрібно, щоб таке неявне перетворення мало місце, то можна запобігти цьому за допомогою специфікатора explicit. Ключове слово explicit застосовується тільки до конструкторів. Конструктор, визначений за допомогою специфікатора explicit, буде задіяний тільки у тому випадку, якщо для ініціалізації членів-даних класу використовується звичайний синтаксис конструктора. Ніяких автоматичних перетворень виконано не буде. Наприклад, оголошуючи конструк­тор класу myClass з використанням специфікатора explicit, ми, тим самим, відмі­няємо підтримку автоматичного перетворення типів. У цьому варіанті визначення класу функція myClass() оголошується як explicit-конструктор.

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

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

class myClass {// Оголошення класового типу int а; public:

explicit myClass(int х) {а = х;} int PutO {return а;}

};

Тепер буде дозволено до застосування тільки конструктори, які задаються в тако­му форматі:

myClass 0bjA(110);

Потреба неявного перетворення конструктора. Автоматичне перетворення з типу аргумента конструктора у виклик конструктора саме по собі має цікаві нас­лідки. Розглянемо, наприклад, такий код програми.

Код програми 11.13. Демонстрація механізму використання неявного перетворення конструктора #include <iostream> // Для потокового введення-виведення

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

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

int п; public:

myClass(int с) {n = с;} int PutO І return n;}

};

int mainO

{

myClass 0bj(10);

cout« Obj.PutO « endl; // Відображає 10

// Тепер використовуємо неявне перетворення для присвоєння нового значення.

Obj = 1000;

cout« Obj.PutO << endl; // Відображає 1000 getchO; return 0;

}

Зверніть увагу на те, що нове значення присвоюється об'єкту Obj за допомо­гою такої настанови:

Obj = 1000;

Використання такого формату можливе завдяки опосередкованому перетворенню з типу int в тип myClass, яке створюється конструктором myClass(). Звичайно ж, якби конструктор myClass() було оголошено за допомогою специфікатора explicit, то по­передня настанова не могла б виконатися.

  1. Синтаксис механізму ініціалізації членів-даних класу

У прикладах програм, наведених у попередніх розділах, члени-даних набува­ли початкові значення у конструкторах своїх класів. Наприклад, наведений нижче код програми починається з клас myClass, який містить два члени-даних а і Ь. Ці члени ініціалізувалися у конструкторі myClass().

Код програми 11.14. Демонстрація механізму ініціалізації членів-даних з використанням конструкторів класу #include <iostream> // Для потокового введення-виведення

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

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

int а, Ь; public:

// Ініціалізація а і b у конструкторі myClassO, використовуючи звичайний синтаксис. myClass(int х, int у) {а = х; b = у;} int PutAO {return а;} int PutBO {return b;}

};

int mainO

{

myClass ObjA(7,9), ObjB(5, 2);

cout«"Значення об'єкта ObjA =" « ObjA.PutBO «" і" « ObjA.PutA() « endl; cout«"Значення об'єкта ObjB =" « ObjB.PutBO <<" і" << ObjB.PutA() « endl; getchO; return 0;

}

Внаслідок виконання ця програма відображає на екрані такі результати: Значення змінних об'єкта ObjA дорівнює 9 і 7 Значення змінних об'єкта ObjB дорівнює 2 і 5

Присвоєння початкових значень членам-даних а і b у конструкторі, як це ро­биться у конструкторі myClass(), - звичайна практика, яка застосовується для ба­гатьох класів. Але цей метод придатний не для всіх випадків. Наприклад, якби члени а і b були задані як const-змінні, тобто так: class myClass {// Оголошення класового типу const int а; // const-член const int b; // const-член,

то їм не можна було б присвоїти значення за допомогою конструктора класу myClass, оскільки const-змінні повинні ініціалізуватися одноразово, після чого їм вже не можна надати інші значення. Такі проблеми виникають при використанні посилальних членів, які повинні ініціалізуватися, і при використанні членів класу, які не мають конструкторів за замовчуванням. Для вирішення проблем такого ро­ду у мові програмування C++ передбачено підтримку альтернативного синтаксису ініціалізації членів-даних класу, який дає змогу присвоювати їм початкові значен­ня при створенні об'єкта класу.

Синтаксис ініціалізації членів-даних класу аналогічний тому, який викорис­товують для виклику конструктора базового класу. Ось як виглядає загальний фо­рмат такої ініціалізації:

constructor (перелік_аргументів): член 1 (ініціалізація),

член2(ініціалізація),

II...

nnenuN (ініціалізація)

{

// Тіло конструктора

}

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

Нижче представлена попередня програма, але перероблена так, щоби члени а і b були оголошені з використанням модифікатора const, і набували свої початкові значення через альтернативний синтаксис ініціалізації членів-даних класу.

Код програми 11.15. Демонстрація механізму оголошення членів-даних класу з використанням модифікатора const #include <iostream> // Для потокового введення-виведення

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

class myClass {// Оголошення класового типу const int а, b; // const-члени public:

// Ініціалізація членів а і b з використанням альтернативного синтаксису ініціалізації. myClass(int х, int у): а(х), Ь(у) {} int PutAO {return а;} int PutBO {return b;}

};