Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Бичков - Основи сучасного програмування.doc
Скачиваний:
81
Добавлен:
07.03.2016
Размер:
3 Мб
Скачать
☆

7.4.10. Покажчик на void

Покажчику на тип void можна присвоїти значення покажчика на будь-який базовий тип. Наприклад:

Void*void_ptr;

int*int_ptr=0x256;

void_ptr=int_ptr;

int_ptr=void_ptr;//невiрно

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

Void swap(void*&item1,void*&item2)

{void*temp=item1;

item1=item2;

item2=temp;}

main()

{int*i=new int,*j=new int;

*i=5;

*j=20;

swap(i,j);

print("*i=%d*j=%d\n",*i,*j);

float*y=new float;*x=new float;

*x=5.0;

*y=20.0;

swap(x,y);

printf("*x=%f*j=%f\n",*i,*j);}

У деяких версіях компілятора С++ (напр., Borland 3.11) ця функція не працює. Тоді необхідно явно вказувати перетворення типу до void*:

swap((void*)i,(void*)j);

7.4.11. Зв'язування зі збереженням типів

У С++ усі імена функцій кодуються компілятором. Тому для використання С-функцій вони мають бути оголошені:

extern"C"

{//визначення чи прототипи С-функцій}

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

extern C

{#include<stdio.h>}

Це приведе до того, що всі прототипи функцій у stdio.h не кодуватимуться. Програма С++ у цьому випадку може використовувати одне чи більше імен функцій зі <stdio.h> без недопустимого перевантаження.

7.4.12. Про структури та об'єднання

У С++ структури та об'єднання мають деякі нові властивості. На відміну від ANSI C, полями структур та об'єднань можуть бути функції. Крім того, структури та об'єднання мають інші властивості, аналогічні й для класів. У літературі інколи класи, структури та об'єднання навіть розглядають разом. Структури та класи відрізняються лише тим, що члени класу за умовчанням мають режим доступу private, а члени структури – public.у. Деякі відмінності мають об'єднання. В об'єднаннях не допускаються ключові слова private, public та protected. Об'єднання не можуть брати участь у механізмі успадкування. У С++ допускаються неіменовані об'єднання:

union{список членів};

Вони визначають об'єкт, а не тип. Імена членів такого об'єднання мають бути унікальними в межах області видимості. Члени використовуються безпосередньо, без операції доступу до них. Однак, оскільки вони є членами об'єднання, то для них виділяється одне й те саме місце, вони мають одну й ту саму адресу. Наприклад:

main()

{union{long l;

unsigned char ch[4]};

cout<<"введіть число типу long:";

cin>>l;

cout<<"молодший байт"<<(int)ch[0]<<"\n";

cout<<"другий байт"<<(int)ch[1]<<"\n";

cout<<"третій байт"<<(int)ch[2]<<"\n";

cout<<"старший байт"<<(int)ch[3]<<"\n";

return 0;}

7.5. Функції-члени класу

7.5.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;}};

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

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

7.5.2. Покажчик this

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]