Роздільне оголошення і визначення полів класу 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Роздільне оголошення і визначення полів класу



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

static int count; //оголошення статичного поля

int foo:: count=0; //Визначення cтатичного поля

 

Для чого використовується така двоїста форма? Якби означення статичного поля знаходилося всередині класу, то це порушило б принцип, згідно з яким визначення класу не повинне бути зв’язаним з виділенням пам’яті. Помістивши визначення статичного поля поза класом, ми забезпечили однократне виділення пам’яті під це поле до того, як програма буде запущена на виконання і статичне поле в цьому випадку стане доступним всьому класу. Кожен об’єкт класу вже не буде володіти своїм власним екземпляром поля, як це повинне бути з полями автоматичного типу. В цьому сенсі статичні поля нагадують глобальні змінні.

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

 

Константні методи

Константні методи відрізняються тим, що не міняють значень полів свого класу. Розглянемо це на прикладі:

class aclass

{private:

int alpha;

public:

void nonfunc() //неконстантний метод

{alpha=99;} //коректно

void confiunc() const //константний метод

{alpha=99;} //некоректно: не можна міняти значення поля

};

Звичайний метод nonfunc() може поміняти значення поля, а константний метод confunc() не може. Якщо константний метод спробує поміняти значення поля, компілятор видасть повідомлення про помилку.

Для того, щоб зробити функцію константною, необхідно вказати ключове слово const після прототипу функції, але до початку тіла функції. Якщо оголошення і визначення функції розділені, то модифікатор const необхідно вказати двічі – як при оголошенні функції, так і при її визначенні. Ті методи, які тільки зчитують дані з поля класу, є сенс робити константними, оскільки у них нема необхідності змінювати значення полів об’єктів класу.

Використання константних функцій допомагає компілятору виявляти помилки. Ще за їх допомогою можна створювати і використовувати константні об’єкти.

Проілюструємо це на прикладі, оголосивши константними деякі методи класу Distance програми 9.7. Одержимо програму 9.9

 

#include <iostream.h>

#include <conio.h>

#include <bios.h>

class Distance

{private:

int feet;

float inches;

public:

 

Distance():feet(0),inches(0.0) //конструктор без аргументів

{ }

 

//конструктор з 2 aргументами

Distance(int ft,float in):feet(ft),inches(in)

{ }

 

void getdist()

{cout <<"\nВведіть число футів "; cin >>feet;

cout << "дюймів "; cin>>inches;

}

 

void showdist() const

{cout <<feet << "\' "<< inches <<"\''";}

 

Distance add_dist(const Distance)const; //Прототип

};

//dodavanna d2 i d3

Distance Distance::add_dist(const Distance d2)const

{

Distance temp;

//feet=0; //помилка не можна міняти поле

//d2.feet=0; //помилка не можна міняти поле

temp.inches=inches+d2.inches;

 if(temp.inches>=12.0)

 {temp.inches-=12.0;

 temp.feet++;}

 temp.feet+=feet+d2.feet;

 return temp;

}

 

int main()

{

clrscr();

Distance dist1,dist3;

Distance dist2(11,6.25);

dist1.getdist();

dist3=dist1.add_dist(dist2);

cout <<"\ndist1=";dist1.showdist();

cout << "\ndist2=";dist2.showdist();

cout << "\ndist3=";dist3.showdist();

cout <<endl;

bioskey(0);

return 0;

}

Програма 9.9

В цьому прикладі обидві функції showdist() та add_dist() є константними. В тілі функції add_dist() перший із закоментованих операторів feet=0; демонструє, що компілятор видасть помилку при спробі зміни константною функцією полів об’єкта, з якого вона викликалася.

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

Distance Distance::add_dist(const Distance d2)const

Функція не може поміняти значення цього аргумента, що і видно на прикладі другого закоментованого оператора d2.feet=0;

 

Константні об’єкти

В кількох попередніх прикладах ми бачили, що ключове слово const можна використовувати для захисту від зміни значень змінних стандартних типів, наприклад, int. Виявляється, аналогічним способом можна застосовувати модифікатор const і для об’єктів класів. Якщо об’єкт класу оголошений з модифікаторм const, він стає недоступним для зміни. Це означає, що для такого об’єкта можна викликати тільки константні методи, оскільки лише вони гарантують, що об’єкт не буде змінений. В якості прикладу розглянемо програму 9.10.

#include <iostream.h>

#include <conio.h>

#include <bios.h>

class Distance

{private:

int feet;

float inches;

public:

//Конструктор з 2 аргументами

Distance(int ft,float in):feet(ft),inches(in)

{ }

void getdist() //Неконстантний метод

{cout <<"\nВведіть число футів "; cin >>feet;

cout << "дюймів "; cin>>inches;

}

 

void showdist() const //Константний метод

{cout <<feet << "\' "<< inches <<"\''";}

};

 

 

int main()

{

clrscr();

const Distance football(300,0);

//football.getdist();

cout <<"Довжина поля=";

football.showdist();

cout <<endl;

bioskey(0);

return 0;

}

 

Програма 9.10

Об’єкт football оголошений як константний, тому для нього можна викликати тільки константні методи, наприклад, showdist(). Виклики неконстантних методів, таких як getdist(), є некоректними.

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

 

Підсумок

Клас являє собою образ, що визначає структуру своїх об’єктів. Об’єкти включають в себе як дані, так і функції, призначені для їх обробки. І дані, і функції можуть бути визначені як закриті, що означає їх доступність тільки для членів даного класу; та як відкриті, тобто доступні для будь-якої функції програми. Закритість членів класу задається ключовим словом private, а відкритість – ключовим словом public.

Методом класу називається функція, що є членом цього класу. Методи класу, на відміну від інших функцій, мають доступ до закритих членів класу.

Конструктор – це метод класу, ім’я якого співпадає з іменем класу і який виконується кожен раз при створенні нового об’єкту. Конструктор не має типу повернутого значення, однак може приймати аргументи. Часто конструктор використовується для ініціалізації створюваних об’єктів класу. Конструктори допускають перезавантаження, тому можлива ініціалізація об’єкту кількома способами.

Деструктор – це метод класу, іменем якого є ім’я класу, перед яким проставлений знак ~. Виклик деструкторів відбувається при знищенні об’єкту. Деструктор не має ні аргументів, ні значення, яке повертається.

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


 

Питання по темі

1. У визначенні класу члени класу з ключовим словом private доступні:

а) для будь-якої функції програми

б) для користувачів, які знають пароль

в) методам класу

г) тільки відкритим членам класу

 

2. Операція крапки (операція доступу до члена класу об’єднує такі два елементи (зліва направо):

а) член класу і об’єкт класу

б) об’єкт класу і клас

в) клас і член цього класу

г) об’єкт класу і член цього класу

 

3. Посилання повідомлення об’єкту еквівалентне

а) виклику методу цього об’єкта

б) створенню об’єкта

в) видаленню об’єкта

 

4. Конструктор викликається автоматично в момент _______ об’єкта

а) звертання до об’єкта

б) створення об’єкта

в) видалення об’єкта

г) копіювання об’єкта

 

5. Ім’я конструктора у С++

а) Init

б) Done

в) Create

г) співпадає з іменем класу

 

6. Чи правильне твердження: один клас може мати кілька конструкторів?

а) так

б) ні

в) тільки клас, що не містить константних методів

 

7. Де, як правило, в конструкторі записується ініціалізація полів об’єкта?

а) між прототипом методу і тілом функції

б) в тілі функції

в) після тіла функції

 

8. Вираз Cl cl2=cl1; де Cl – ідентифікатор об’єктного типу, є:

а) оператором присвоювання

б) викликом конструктора копіювання за замовчуванням

в) викликом одного з методів класу

 

9. Деструктори:

а) не мають аргументів і не повертають жодного значення

б) не мають аргументу, але повертають значення у викликаючу програму

в) можуть мати аргументи і не повертають значення у викликаючу програму

 

10. Методу класу доступні дані:

а) об’єкта, членом якого він є

б) класу, членом якого він є

в) будь-якого об’єкту класу, членом якого він є

д) класу, оголошеного відкритим

 

11. Операція глобального дозволу позначається символом:

а)::

б):

в) _

 

 

12. Нехай оголошені три об’єкти класу. Скільки копій полів класу міститься в пам’яті? Скільки копій методів функції?

а) три копії полів і три копії методів

б) три копії полів і одна копія методів

в) одна копія полів і одна копія методів

 

13. Роздільне оголошення і визначення полів класу здійснюється для:

а) закритих полів

б) відкритих полів

в) статичних полів

 

14. Константний метод, викликаний для об’єкту класу:

а) може змінювати як константні, так і неконстантні поля

б) може змінювати тільки неконстантні поля

в) може змінювати тільки константні поля

г) не може змінювати ні константні, ні некостантні поля

 

15. Чи істинне твердження: об’єкт, оголошений як константний, можна використовувати тільки за допомогою константних методів?

 


Тема 10. Перезавантаження операцій в С++

 

Вступ

Перезавантаження унарних операцій

Ключове слово operator

Аргументи операції

Значення, що повертаються операцією

Тимчасові безіменні об’єкти

Постфіксні операції

Перезавантаження бінарних операцій

Арифметичні операції

Об’єднання рядків

Множинне перезавантаження

Операції порівняння

Операції арифметичного присвоювання

Операція індексації масиву

Перетворення типів

Перетворення основних типів у основні типи

Перетворення об’єктів у основні типи і навпаки

Перетворення рядків в об’єкти класу String і навпаки

Перетворення об’єктів класів в об’єктів інших класів

Деякі рекомендації щодо перезавантаження операцій і перетворення типів

Коли які перетворення використовувати?

«Підводні камені» перезавантаження операцій і перетворення типів

Підсумок

Питання по темі

 

Вступ

Перезавантаження операцій в - одна з найпривабливіших можливостей ООП, Воно може перетворити складний і малозрозумілий лістінг в інтуїтивно зрозумілий. Наприклад, рядки:

d3.addobjects(d1,d2);

або

d3=d1.addobjects(d2)

можна замінити на більш читабельний вираз

d3=d1+d2;

Термін «перезавантаження операцій» дається звичайним операціям С++, таким як +, -, *, >= чи += у випадку їх використання з визначеними користувачем типами даних.

Звичайно оператори виду

a=b+c;

працюють лише з основними типами даних, такими як int чи float, і спроби використання звичайних операторів, коли операнди є об’єктами визначеного користувачем класу, викличуть протест компілятора. Однак, використовуючи перезавантаження, ми можемо зробити подібні записи правильними.

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

Інший вид дій, перетворення типів, тісно зв’язаний з перезавантаженням операцій. С++ здійснює перетворення простих типів, таких як int чи float, автоматично, але перетворення, що включає в себе створені користувачем типи, вимагає виконання певної роботи програмістом.

 



Поделиться:


Последнее изменение этой страницы: 2021-12-15; просмотров: 99; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.191.135.224 (0.07 с.)