Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lutsik_Yu_A_Obektno_orientir_programmir_na_yaz.pdf
Скачиваний:
63
Добавлен:
11.05.2015
Размер:
4.33 Mб
Скачать

3.5. Указатель this

Как отмечалось выше, если некоторая функция является компонентой объекта, то при вызове этой функции к компонентам-данным этого объекта можно обращаться по имени (опуская имя объекта). Например, пусть имеется объявление двух объектов:

my_class ob1,ob2;

Вызовы компонент-функций имеют вид ob1.fun_1();

ob2.fun_2();

Пусть в обеих функциях содержится инструкция Р cout << str;

При объявлении двух объектов создаются две компонентыИ-данные str. Возникает вопрос, откуда каждая из двух функций узнает, с какой из компонент ей работать (точнее, где она расположена). Ответ состоит в Уследующем. В па- мяти для каждого располагаемого объекта создается скрытыйГуказатель, ад- ресующий начало выделенной под объект области памяти. Получить значение этого указателя в компонентах-функциях можно посредством ключевого слова this. Для любой функции, принадлежащей классу my class, указатель this неявно

объявлен так:

ая

my_class *const this;

к

Б

Таким образом, при объявлении объе тов ob1 и ob2 создаются два this- указателя на эти объекты. Следовательно, люб функция, являющаяся компо-

нентой некоторого объекта, при вызо получает this-указатель на этот объект.

И приведенная выше инструкция в функции воспринимается как

cout << this->str;

 

 

ве

Однако эта форма записи избы очна. С другой стороны, явное использо-

вание указателя this эффект в при решении некоторых задач.

 

и

 

Рассмотрим пример

сп льзтвания this-указателя на примере упорядочи-

л

но

 

вания чисел в массиве.

 

 

#include<iostream>

 

 

using namespace std;

 

 

и

 

 

 

#include<stdio.h>

 

 

 

Б

 

 

 

class m clб

 

 

 

{ int a[3];

 

 

 

public:

 

 

 

m cl srt();

 

// функция упорядочивания информации в массиве

m_cl *inpt();

 

// функция ввода чисел в массив

void out();

 

// вывод информации о результате сортировки

};

 

 

 

m_cl m_cl::srt()

 

// функция сортировки

{for(int i=0;i<2;i++) for(int j=i;j<3;j++)

36

 

if (a[i]>a[j]) {a[i]=a[i]+a[j]; a[j]=a[i]-a[j]; a[i]=a[i]-a[j];}

 

return *this;

 

// возврат содержимого объекта, на который

 

}

 

 

 

// указывает указатель this

 

m_cl * m_cl::inpt()

// функция ввода

 

 

{ for(int i=0;i<3;i++)

 

 

 

 

 

cin >> a[i];

 

 

 

 

 

 

return this;

 

// возврат скрытого указателя this

 

}

 

 

 

// (адреса начала объекта)

 

void m_cl::out()

 

 

 

 

 

 

{ cout << endl;

 

 

 

 

Р

 

for(int i=0;i<3;i++)

 

 

 

 

cout << a[i] << ' ';

 

 

 

 

}

 

 

 

 

 

 

И

 

main()

 

 

 

 

 

 

 

{ m_cl o1,o2;

 

// описание двух объектов класса m_cl

 

o1.inpt()->srt().out();

 

 

 

У

 

// вызов компонент-функций первого объекта

 

o2.inpt()->srt().out();

// вызов компонентГ-функций второго объекта

 

return 1;

 

 

 

 

Б

 

 

}

 

 

 

 

 

 

 

Вызов компонент-функций для

 

ждого из созданных объектов осущест-

вляется

 

 

 

а

 

 

o1.inpt()->srt().out;

 

 

к

 

 

 

 

 

 

 

 

 

 

Приведенная инструкция инт рпретируется следующим образом:

 

сначала вызывае ся функцияеinpt для ввода информации в массив данных

объекта о1;

 

 

 

 

 

 

 

 

функция inpt в звращ

адрес памяти, где расположен объект о1;

 

далее вызываетсяаетфункция сортировки информации в массиве, возвра-

щающая соде

 

м

объекта о1;

 

 

 

 

 

 

ое

 

 

 

 

 

пос е этого вызывается функция вывода информации.

 

 

ржи

 

 

 

 

 

 

Ниже приведен текст еще одной программы, явно использующей указа-

тель this. лВ ней выполняется добавление строки-компоненты одного объекта к

строке-компоненте другого.

 

 

 

 

 

б

 

 

 

 

 

 

 

 

#include<iostream.h>

 

 

 

 

и

 

 

 

 

 

 

 

Б

#include<string.h>

 

 

 

 

class B;

 

 

// предварительное объявление класса В

class A

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

{ char *s;

 

 

 

 

 

 

 

public:

 

 

 

 

 

 

 

 

A(char *s)

// конструктор с параметром char*

 

{ this->s=new char[strlen(s)+1];

// память под строку-компоненту

 

strcpy(this->s,s);// копирование строки-аргумента в строку-компоненту

 

 

 

 

 

 

 

 

37

}

~A(){delete [] this->s;} void pos_str(char *);

};

 

class B

 

{ char *ss;

 

public:

 

B(char *ss)

// конструктор с параметром char*

{char *dd; БГУИР int i,ii;

dd=new char[strlen(this->s)+strlen(s)+2];амя//п ть для перезаписи 2 строк strcpy(dd,this->s); // перезапись в dd строки объекта a1 dd[strlen(this->s)]=' '; // удаление ’\0’к

ii=strlen(this->s);

for(i=0;*(s+i);i++) // дозаписьев dd строки объекта b1

 

delete [] this->s;

 

 

// удаление с роки объекта a1

 

this->s=dd;

 

 

о

 

 

 

 

 

// перенаправление указателя на строку dd

 

 

 

и

т

}

cout << this->s << endl;

 

 

 

 

 

 

 

 

void main(void)

 

 

 

 

 

 

б

 

 

 

 

 

{ A a1("aa bcc dd ee");

 

 

 

 

B b1("bd");

л

 

 

 

 

}

a1.pos str(b1.f_this());

 

 

 

 

 

 

 

 

 

 

В результатеи

выполнения программы получим

aa bcc dd ee bd

 

 

 

 

 

БОтметим основные правила использования this-указателей:

-каждому объявляемому объекту соответствует свой скрытый this- указатель;

-this-указатель может быть использован только для нестатической функции;

-this указывает на начало своего объекта в памяти;

-this не надо дополнительно объявлять;

38

inline int stroka ::size() { for(int i=0; str[i]; i++);
return i;

-this передается как скрытый аргумент во все нестатические (не имеющие спецификатора static) компоненты-функции своего объекта;

-указатель this − локальная переменная и недоступна за пределами объекта;

-обращаться к скрытому указателю можно this или *this.

3.6. Встроенные функции (спецификатор inline)

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

мяти на хранение кода самой функции. Для таких функций целесообразно по-

местить код функции вместо выполнения перехода к функцииР. В этом случае

 

 

 

 

 

 

 

У

при выполнении функции (обращении к ней) выполняется сразу ее код. Функ-

 

 

 

 

 

 

Г

ции с такими свойствами являются встроенными. Иначе Иговоря, если описание

компоненты функции включается в класс, то такая функция называется встро-

енной. Например:

 

 

 

Б

 

 

 

 

 

 

class stroka

 

 

а

 

{ char str[100];

 

 

 

 

public:

 

 

 

 

 

……..

 

е

 

 

int size()

 

 

 

{ for(int i=0; *(str+i); i++);к

 

 

 

}

return i;

т

 

 

 

 

 

 

 

 

 

};

о

 

 

 

 

 

 

 

 

 

 

ци

 

 

 

 

 

В описанн м примере функция size() – встроенная. Если функция, объяв-

ленная в классе, а писанная за его пределами, должна быть встроенной, то она

 

л

описывается со спе фикатором inline:

 

class stroka

 

{ char str[100];

и

Б

public:

б……..

 

int size();

};

}

Спецификация inline может быть проигнорирована компилятором, по-

скольку иногда введение встроенных функций оказывается невозможным или нежелательным.

39

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