Константные объекты и константные методы

имя_типа * const this

const имя_типа *const this

Если метод не встраиваемый, то слово const должно быть в объявлении и определении. В связи с этим, могут существовать два одноименных метода, отличающихся только наличием или отсутствием атрибута const. Для const-объектов будет вызываться только константный метод. При существовании одного лишь константного метода он будет вызываться для любых объектов, т.к. преобразование не константного объекта к константному - безопасно.

Иногда требуются исключения из правил доступа, когда некоторой функции или классу требуется разрешить доступ к личной части объекта класса. Это согласуется с тем принципом, что сам класс определяет права доступа к своим объектам "со стороны". К средствам контроля доступа относятся объявления функций-членов константными (const). В этом случае они не имеют права изменять значение текущего объекта, с которым вызываются. Заголовок такой функции при этом имеет вид

void dat::put() const

{ ... }

Аналогично можно определить константные объекты:

const class a{...} value;

Константные методы

1) не должны менять значения элементов класса;

2) не должны вызывать другие неконстантные методы класса.

Константные методы могут применяться как для константных, так и для неконстантных объектов.

\\Любой объект пользовательского типа может быть объявлен как константа.

const Point2d d(5,4);

double mod() const

{

return sqrt(x*x+y*y);

}

Для константных методов указатель this будет иметь следующее описание:

const имя_класса const *this;

В связи с такой трактовкой, в классе может существовать два одноименных метода, отличающиеся наличием или отсутствием const. Для константных объектов будет вызываться только константный метод, а для неконстантных – неконстантный. При существовании одного лишь константного метода, он будет вызываться для всех объектов, т.к. преобразование неконстанного объекта в константный – безопасно.

Неявный указатель this

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

имя_класса *const this = адрес_объекта

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

void complex add(complex ob)

{

this->re=this->re+ob.re;

// или *this.re=*this.re+ob.re

this->im=this->im+ob.im;

}

Если функция возвращает объект, который ее вызвал, используется указатель this.

Например, пусть функция add возвращает ссылку на объект. Тогда

complex& complex add(complex& ob)

{

re=re+ob.re;

im=im+ob.im;

return *this;

}

Каждый не статический метод класса содержит в качестве данного указатель "this".

В функции - члене на данные - члены объекта, для которого она была вызвана, можно ссылаться непосредственно. Например:

class x

{

int m;

public:

int readm()

{

return m;

}

};

x aa;

x bb;

void f()

{

int a = aa.readm();

int b = bb.readm(); // ...

}

В первом вызове члена readm() m относится к aa.m, а во втором - к bb.m.

Указатель на объект, для которого вызвана функция-член, является скрытым параметром функции. На этот неявный параметр можно ссылаться явно как на this. В каждой функции класса x указатель this неявно описан как x* this и инициализирован так, что он указывает на объект, для которого была вызвана функция-член. this не может быть описан явно, так как это ключевое слово.

Главным образом this используется при написании функций членов, которые манипулируют непосредственно указателями.

Указатели на член класса

int a;

int *pa;

pa=&a;

*pa=10;//разадресация

//указатели на функции

void f();

void(*pf)();

pf=f;//настройка указателя на конкретную функцию.

(*pf)();//обращение к функции f

pf();//компактное обращение

class Point2D

{

public:

double x,y;

double mod() const;

};

Point2D a(3,5);

double *pd;

pd=&a.x;

*pd=10;

pd=a.y;

*pd=15;

в С++ было введено специальное средство для написания указателей без привязки к объекту.

double Point2D::*pd;

double (Point2D::*pf)()const;

Настройка этих указателей проводится без указания конкретного объекта и даже при отсутствии класса элемента.

pd=&Point2d::x;//настройка указателя на данные класса

pf=&Point2D::mod;//

Можно считать, что у каждого объекта класса есть свое пространство адресов, а указатель на члены класса не что иное, как адреса в этом пространстве.

Данные операции служат для разыменовывания указателя на член класса: .* и ->*

Point2D a(2,3), *pa=&a;

Point2D b(3,4), *pb=&b;

a.*pd=10;//a.x=10

pa->*pb=10;

b.*pb=10;

pb->*b=12;//pb->x=12

cout<<(a.*pf)();

Многие классы предоставляют простые и очень общие интерфейсы, которые предполагают средства несколькими способами.


Наши рекомендации