Здавалка
Главная | Обратная связь

Ім'я_об'єкта. ім'я_функції



Наприклад:

complex x1,x2;

x1.re = 1.24;

x1.im = 2.3;

x2.set(5.1,1.7);

x1.print();

Другий спосіб доступу використовує покажчик на об'єкт

покажчик_на_об'єкт–>ім'я_компонента

complex *point = &x1; // чи point = new complex;

point –>re = 1.24;

point –>im = 2.3;

point –>print();

Доступність компонентів класу

У розглянутих раніше прикладах класів компоненти класів є загальнодоступними. У будь-якому місці програми, де “видно” визначення класу, можна одержати доступ до компонентів об'єкта класу. Тим самим не виконується основний принцип абстракції даних – інкапсуляція (приховання) даних всередині об'єкта. Для зміни видимості компонент у визначенні класу можна використовувати специфікатори доступу : public, private, protected.

Загальнодоступні (public) компоненти доступні в будь-якій частині програми. Вони можуть використовуватися будь-якою функцією як всередині даного класу, так і поза ним. Доступ ззовні здійснюється через ім'я об'єкта :

ім'я_об'єкта.ім'я_члена_класу;

посилання_на_об’єкт.ім'я_члена_класу;

покажчик_на_об'єкт->ім'я_члена_класу;

Власні (private) компоненти локалізовані в класі і не доступні ззовні. Вони можуть використовуватися функціями-членами даного класу і функціями-“друзями” того класу, в якому вони описані.

Захищені (protected) компоненти доступні всередині класу і в похідних класах.

Змінити статус доступу до компонентів класу можна і за допомогою використання у визначенні класу ключового слова class. У цьому випадку усі компоненти класу за замовчуванням є власними.

Приклад.

class complex

{

double re, im; // private за замовчуванням

public:

double real(){return re;}

double imag(){return im;}

void set(double x,double y){re = x; im = y;}

};

Конструктор.

Недоліком розглянутих раніше класів є відсутність автоматичної ініціалізації створюваних об'єктів. Для кожного знову створюваного об'єкта необхідно було викликати функцію типу set (як для класу complex), або явно привласнювати значення даним об'єкта. Однак для ініціалізації об'єктів класу в його визначення можна явно включити спеціальну компонентну функцію, що називається конструктором. Формат визначення конструктора наступний

ім'я_класу(список_форм_параметрів){оператори_тіла_конструктора}

Ім'я цієї компонентної функції за правилами мови С++ повинно збігатися з ім'ям класу. Така функція автоматично викликається при визначенні чи розміщенні в пам'яті за допомогою оператора new кожного об'єкта класу.

Приклад

сomplex(double re1 = 0.0,double im1 = 0.0){re = re1; im = im1;}

Конструктор виділяє пам'ять для об'єкта та ініціалізує дані- члени класу.

Конструктор має ряд особливостей:

* Для конструктора не визначається тип значення, що повертається. Навіть тип void не припустимий.

* Покажчик на конструктор не може бути визначений і відповідно не можна одержати адресу конструктора.

* Конструктори не успадковуються.

* Конструктори не можуть бути описані з ключовими словами virtual, static, const, mutuable, valatile.

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

Параметром конструктора не може бути його власний клас, але може бути посилання на нього (T&). Без явної вказівки програміста конструктор завжди автоматично викликається при визначенні (створенні) об'єкта. У цьому випадку викликається конструктор без параметрів. Для явного виклику конструктора використовуються дві форми:

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

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

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

complex ss(5.9,0.15);

Друга форма виклику приводить до створення об'єкта без імені:

complex ss = complex(5.9,0.15);

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

ім'я_даного(вираження)

Приклади.

class CLASS_A

{

int i; float e; char c;

public:

CLASS_A(int ii,float ee,char cc) : i(8),e( i * ee + ii ),з(сс){}

. . .

};

Клас “символьний рядок”.

#include <string.h>

#include <iostream.h>

class string

{

char *ch; // покажчик на текстовий рядок

int len; // довжина текстового рядка

public:

// конструктори

// створює об'єкт – порожній рядок

string(int N = 80): len(0){ch = new char[N+1]; ch[0] = '\0';}

// створює об'єкт по заданому рядку

string(const char *arch){len = strlen(arch);

ch = new char[len+1];

strcpy(ch,arch);}

// компонента-функції

// повертає посилання на довжину рядка

int& len_str(void){return len;}

// повертає покажчик на рядок

char *str(void){return ch;}

. . .};

Тут в класі string два конструктори – функції, що перевантажуються.

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

а)коли об'єкт передається функції за значенням;

б)при побудові тимчасового об'єкта значення функції, що повертається;

в)при використанні об'єкта для ініціалізації іншого об'єкта.

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

string(const string& st)

{len=strlen(st.len);

ch=new char[len+1];

strcpy(ch,st.ch); }

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

Масив об'єктів може ініціюватися або автоматично конструктором за замовчуванням, або явним присвоюванням значень кожному елементу масиву.

class demo{

int x;

public:

demo(){x=0;}

demo(int i){x=i;}

};

void main(){

class demo a[20]; //виклик конструктора без параметрів(за замовчуванням)

class demo b[2]={demo(10),demo(100)};//явне присвоювання

Деструктор.

Динамічне виділення пам'яті для об'єкта створює необхідність звільнення цієї пам'яті при знищенні об'єкта. Наприклад, якщо об'єкт формується як локальний всередині блоку, то доцільно, щоб при виході з блоку, коли вже об'єкт перестає існувати, виділена для нього пам'ять була повернута. Бажано щоб звільнення пам'яті відбувалося автоматично. Таку можливість забезпечує спеціальний компонент класу – деструктор класу. Його формат:

~ім’я_класу( ){оператори_тіла_деструктора}

Ім'я деструктора збігається з ім'ям його класу, але добавляється префіксний символ “~” (тильда).

Деструктор не має параметрів і значення, що повертається. Виклик деструктора виконується не явно (автоматично), як тільки об'єкт класу знищується.

Наприклад, при виході за область визначення або при виклику оператора delete для покажчика на об'єкт.

string *p=new string(“рядок”);

delete p;

Якщо в класі деструктор не визначений явно, то компілятор генерує деструктор за замовчуванням, що просто звільняє пам'ять, зайняту даними об'єкта. У тих випадках, коли потрібно виконати звільнення й інші об'єкти пам'яті, наприклад область, на яку вказує ch в об'єкті string, необхідно визначити деструктор явно: ~string(){delete []ch;}

Також як і для конструктора, не може бути визначений покажчик на деструктор.







©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.