Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курс лекцій.doc
Скачиваний:
15
Добавлен:
03.11.2018
Размер:
1.12 Mб
Скачать

3 Функції-члени.

3.1 Функції-члени в межах та за межами формального опису класу.

Як вже відмічалось, тіло функції-члена може бути визначене як в межах формального опису класу так і за його межами. В першому випадку компілятор розглядає функцію як inline-функцію. Можна явно визначати inline-функцiю за допомогою вiдповiдної директиви:

class x

{ int m;

public :

int readm (void);

};

inline int x :: readm (void)

{return m;}

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

class x

{ int m;

public :

int readm (void)

{return m;}

};

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

Відмітимо, що компілятор з високим рівнем оптимізації може у випадках , коли тіло функції містить багато операторів, не вставляти код програми в місце її виклику, якщо навіть присутній специфікатор inline .

3.2 Про вказівник this.

Як вже відмічалось, в тiлі функцiї-члена оператори мають безпосереднiй доступ до будь-яких полів даних та функцій-членiв, визначених в протоколі.Часто в протоколі опису класу виникає необхідність викликати функцію-член всередині іншої функції-члена. Якщо послідовно дотримуватись об’єктно-орієнтованої парадигми, то вкладений виклик функції повинен інтерпретуватись як передача повідомлення об’єкту. Об’єкт, що приймає вкладене повідомлення - це той самий обє’кт, який приймає повідомлення верхнього рівня. Тобто об’єкт повинен “вміти” передавати повідомлення сам собі. Як вийти з цієї ситуації так, щоб повністю підтримувалась концепція ООП ? І вирішена ця проблема наступним чином. В С++ будь-яка функція- член класу має додатковий скритий формальний параметр - вказівник на клас, для екземпляру якого викликається функція-член. Причому він завжди ініціалізується системою С++ так, що вказує на об’єкт, для якого викликається функція-член. Іншими словами, будь-яка функція-член класу Х в сигнатурі містить неявне оголошення виду:

X *this;

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

class Х{

int m ;

public :

int readm (void){ return m;}

};

Функцію-член readm () можна записати і так:

int readm (void){ return this->m;}

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

class dlink {

dlink * pre

dlink * suc;

public:

void append (dlink*);

};

void dlink ::append (dlink*p);

{

p->suc=suc; // тобто p->suc=this->suc;

p->pre=this;

suc->pre=p; //тобто this->suc->pre=p

suc=p;

}

В такій реалізації функція append() вставляє елемент, вказівник на який передається як параметр в функцію, після елемента, який викликав функцію -член append().