Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
c++ ответы.docx
Скачиваний:
2
Добавлен:
01.07.2025
Размер:
36.53 Кб
Скачать

37. Явное и неявное использование указателя this в функциях класса. Организация сцепления вызовов функций класса.

В терминах ООП инкапсуляция проявляется, во-первых, в способе вызова функции класса и, во-вторых, в способе доступе к данных-элементам класса. Следовательно, инкапсуляция – это всего лишь способ адресации при обращении к функциям и данным-элементам класса.

Независимо от языка ООП, инкапсуляция воплощается через режим косвенной адресации. При этом косвенно адресуются не функции класса, а объекты класса, т.е. адреса загрузки объектов в памяти независимо от места их объявления – на внешнем или на внутреннем уровне.

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

Пусть ob и f() соответственно объект и функция некоторого класса. Тогда оператор вызова f() имеет вид: ob. f();. Выполнение этого оператора осуществляется в два этапа. В начале в указатель this функции f() записывается адрес загрузки в памяти объекта ob, затем осуществляется вызов f(). Поскольку указатель this у каждой функции класса единственный, то через this любая функция имеет доступ к переменным только одного объекта, который обусловил вызов этой функции, например с помощью оператора ob.f();.

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

Для переменных и функций класса инкапсуляция проявляется в следующем:

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

  2. При обращении к функциям класса необходимо указывать адрес загрузки объекта, по отношению к которому вызывается функция класса.

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

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

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

Две следующие программы иллюстрируют явное и неявное использование указателя this.

//PROG.2.1.CPP – имя файла

#include<iostream>

using namespace std;

class myclass{

public:

myclass(int n, int m){a=n; b=m;}

int add(){return a+b;}

void print()const;

private:

int a,b;

}

void myclass::print()const

{int sum;

sum= add();

cout<<”Sum = ”<<sum<<endl;}

int main()

{

myclass ob(7,5);

ob.print();

return 0;

}

//PROG.2.2.CPP – имя файла

#include<iostream>

using namespace std;

class myclass{

public:

myclass(int n, int m){this->a=n; this->b=m;}

int add(){return this->a+ this->b;}

void print()const;

private:

int a,b;

}

void myclass::print()const

{int sum;

sum= this->add();

cout<<”Sum = ”<<sum<<endl;}

int main()

{

myclass ob(7,5);

ob.print();

return 0;

}

В не константной функции-элементе add() класса myclass указатель this имеет тип myclass*const this – константный указатель на объект типа myclass. В константой функции-элементе print()const указатель this имеет тип const myclass* const this – константный указатель на константный объект типа myclass. Таким образом, константность функции распространяется только на переменные объекта, косвенно адресуемого через this функции print()const.

Указание const после аргументов функции – защита от не санкционированного изменения аргументов, т.е. использование данных только в режиме чтения.

Содержимое указателя this может возвращаться функциями класса с целью организации последовательности (сцепления) вызовов функций одного класса.

//PROG.2.3.CPP – имя файла

#include<iostream>

using namespace std;//множество имен, отличных от стандартных занятых языком

class myclass{

public:

myclass(int n, int m){a=n; b=m;}

myclass& add(){c=a+b; return * this;}

myclass& sub(){c=a-b; return * this;}

myclass& print(int flag)

{

if(0 == flag) cout<<”Sum = ”<< c <<endl;

else cout<<”Sub = ”<< c <<endl;

return * this;

}

private:

int a,b,c;

}

int main()

{

myclass ob(7,5);

ob.add().print(0).sub().print(1);

return 0;

}

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