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

Указатель this

Каждый объект в C++ содержит специальный указатель с именем this, который автоматически создается самим компиля­тором и указывает на данный объект. Типом this является Т*, где T — тип класса данного объекта. Поскольку указатель this определен в классе, область его действия — класс, в котором он определен. Фактически this является скрытым параметром класса, добавляемым самим компилятором к его определению. При вызове обычной функции-члена класса ей передается указа­тель this так, как если бы он был первым аргументом. Таким образом, вызов функции-члена

ObjName.FuncName(par1, par2);

компилятор трактует так:

ObjName.FuncName(&ОbjName, parl, par2);

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

#include <iostream.h>

#include <string.h>

class Т

{

public:

Т(char*);

void Greeting();

char item[20];

};

Т::Т(char* name)

{

strcpy(item, name);

Greeting(); //Bee три

this->Greeting() ; //оператора

(*this) .Greeting(); //эквивалентны

}

void

T: :Greeting()

{

//Оба нижеследующих оператора эквивалентны

cout «"Hello, " « item « "\n";

cout «"Hello, " « this->item « "\n";

}

int main()

{

Т ob(“dear.”) ;

return 0;

}

Как можно видеть, внутри конструктора класса и функции-члена Greeting() обращения к данным-членам класса и функ­циям-членам могут осуществляться как непосредственно по имени, так и с помощью указателя this. Поэтому на практике такое употребление указателя this встречается крайне редко. В основном указатель this используется для возврата указателя (в форме: return this;) или ссылки (в форме: return *this;) на соответствующий объект. Этот указатель находит широкое применение при перегрузке операторов.

Встраиваемые (inline-) функции

В C++ можно задать функцию, которая, фактически, не вызы­вается, а ее тело встраивается в программу в месте ее вызова. Она действует почти так же, как макроопределение с параметрами. По сравнению с обычными функциями встраиваемые (in-line) функ­ции обладают тем преимуществом, что их вызов не связан с пе­редачей аргументов и возвратом результатов через стек и, следо­вательно, они выполняются быстрее обычных. Недостатком встраиваемых функций является то, что если они слишком боль­шие и вызываются слишком часто, объем программы сильно воз­растает. Из-за этого применение встраиваемых функций обычно ограничивается только очень простыми функциями.

Объявление встраиваемой функции осуществляется с помо­щью спецификатора inline, который вписывается перед опре­делением функции.

Следует иметь в виду, что спецификатор inline только формулирует требование компилятору сформировать встроенную функцию. Если компилятор не в состоянии выполнить это требо­вание, функция компилируется как обычная. Компилятор не мо­жет сгенерировать функцию как встраиваемую, если она:

• содержит оператор цикла (for, while, do-while);

• содержит оператор switch или goto;

• содержит статическую переменную (static);

• если функция является рекурсивной;

• имеет возвращаемый тип, отличный от void, и не содер­жит оператора return;

• содержит встроенный код ассемблера.

Компилятор может налагать и другие ограничения на исполь­зование inline-функций. Уточните их в описании конкретного компилятора. Ниже приведен пример использования встраивае­мой функции:

#include <iostream.h>

inline int even(int x)

{

return !(x%2);

}

int main()

{

int n;

cin » n;

if (even(n))

cout « n « "является четным\n";

else

cout « n « " является нечетным \n";

return 0;

}

В этом примере программа читает введенное целое число и сообщает, является ли оно четным. Функция even () объявлена как встраиваемая. Это означает, что оператор

if (even(n))

cout « n «”является четным\n”

эквивалентен следующему:

if (!(n%2))

cout « n « "является четным\n";

Важно отметить, что встраиваемая функция должна быть не только объявлена, но и определена до ее первого вызова. Поэтому определение inline-функций обычно размещается в заголовочном файле. В приведенном выше примере функция even() была определена до функции main (), в которой она используется.

Встроенными могут быть объявлены не только обычные функции, но и функции-члены. Для этого достаточно включить ее определение в объявление класса (в этом случае ключевое сло­во inline больше не нужно) или перед определением функции вставить ключевое слово inline.

Следующий пример демонстрирует использование встроен­ных функций-членов.

class Point

{

int x;

int у;

public:

int GetX() {return x;} //inline-функция

int GetY() {return у;} //inline-функция

void SetX(int _x){x =_x;} //inline-функция

void SetY(int _y){y =_y;} //inline-функция

};

Можно определить встроенную функцию-член и вне тела класса, предварив ее определение ключевым словом inline:

class Point

{

int x;

int y;

public:

int GetX() ;

int GetY() ;

void SetX(int);

void SetY(int);

};

inline int

Point::GetX()

{

return x;

}

inline int

Point::GetY()

{

return у;

}

void

Point::SetX(int _x)

{

x = _x;

}

void

Point::SetY(int _y)

{

у = _y;

}

Соседние файлы в папке ЯзыкС++Глушаков