Применение указателя this для реализации каскадных вызовов

Указатель this и конструктор копирования

  1. Указатель this
    1. Понятие указателя this
    2. Практические примеры использования указателя this
  2. Конструктор копирования
    1. Понятие побитового копирования
    2. Проблемы, связанные с побитовым копированием
    3. Проблемные ситуации, требующие конструктора копирования (передача по значению объекта, возврат объекта по значению, создание объекта в форме присваивания другого объекта)
    4. Синтаксис конструктора копирования
    5. Примеры использования конструктора копирования (классы Вектор, Строка, Матрица и так далее)
    6. Обсуждение тонкостей конструктора копирования

i. Спецификатор const

ii. Необходимость передачи по ссылке

Урок 4

Указатель this

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

Точнее будет сказать, что указатель this передается (компилятором) в объект в качестве неявного аргумента вызова каждой не статической его функции.

При вызове обычной функции-члена класса ей передается указа­тель this так, как если бы он был первым аргументом. Таким образом, вызов функции-члена

 

ObjName.FuncName(par1, par2);

 

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

 

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

 

Пример 1 демонстрирует явное и неявное использование указателя this; позже в этом уроке и в последующих мы продемонстрируем некоторые важные и тонкие примеры применения этого указателя.

В иллюстративных целях элемент-функция print (строки 25-37) сначала печатает х, используя this неявно (строка 28), указывая только имя элемента. Затем print использует две различные нотации для доступа к х через указатель this — операцию-стрелку (->)с указателем (строка 32) и операцию-точку (.) с разыменованным указателем (строка 36).

Обратите внимание на скобки вокруг *this при использовании указателя this с операцией выбора элемента (.). Скобки необходимы, поскольку операция-точка имеет более высокий приоритет, чем операция *. Без круглых скобок выражение *this.x оценивалось бы как *(this.x), что является ошибкой компиляции, поскольку операция-точка к указателю применяться не может.

Интересным применением указателя this является недопущение присваивания объекта самому себе. Как мы увидим в главе 11, присваивание объекта себе самому может вызвать серьезные ошибки, если объекты содержат указатели на динамически выделенную память.

Указатель this можно также применять для идентификации поля класса в том случае, когда его имя совпадает с именем формального параметра метода. Другой способ идентификации поля использует операцию доступа к области видимости. Пример 2.Строки 27-31.

 

Указатель this неявно используется внутри метода для ссылок на элементы объекта. В явном виде этот указатель применяется в основном для возвращения из метода указателя (return this;) или ссылки (return *this;) на вызвавший объект.

 

Вспомним как из функции можно вернуть ссылку.

 

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

 

Например, для функции, объявленной как:

 

double &func(int p);

 

необходим аргумент целого типа, и она возвращает ссылку на объект double.

 

Пример 3_0. Нахождение максимального элемента в массиве и замена его на нуль.

 

При выполнении строки:

 

cout << "\nrmax(n,x) = " << rmax(n,x) << "\n";

 

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

rmax(n,x) = 0;

 

снова осуществляется обращение к функции rmax(). Теперь уже по найденной ссылке максимальное значение меняется на 0.

 

 

Применение указателя this для реализации каскадных вызовов

Функций

Другим применением указателя this является реализация каскадных вызовов элемент-функций, когда несколько функций вызываются в одном и том же операторе. Программа в Примере 3 модифицирует set-функции setTime, setHour, setMinute и setSecond класса Time таким образом, что каждая из них возвращает теперь ссылку на объект Time, позволяя осуществлять каскадные вызовы элемент-функций. Заметьте, что последний оператор тела каждой из этих функций на рис. возвращает *this при возвращаемом типе Time &.

Программа в Пример 3 создает объект t класса Time (строка 11) и затем использует его для каскадных вызовов элемент-функций (строка 21). Почему работает прием, основанный на возврате *this в качестве ссылки? Операция-точка (.)ассоциируется слева направо, поэтому строка 21 оценивает сначала t.setHour(18), а затем возвращает ссылку на t как значение этого вызова функции. Оставшееся выражение затем интерпретируется как

t.setMinute(30).setSecond(22);

Выполняется вызов t.setMinute(30) и возвращается ссылка на t. Оставшееся выражение интерпретируется как

t.setSecond(22);

Опять возвращается ссылка на t и последней выполняется вызов t.printUniversal().

Вызовы должны выполняться именно в указанном порядке, поскольку определенная в классе функция printStandard не возвращает ссылку на t. Если поместить в в строке 21 вызов printStandard перед вызовом setTime, это приведет к ошибке компиляции. В далее мы приведем ряд практических примеров использования каскадных вызовов функций. В одном из них показано применение операций << с потоком cout для вывода нескольких значений в одном операторе.

 

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

Итак, кое-что о this...

1. this передается в каждую не статическую элемент-ф-ию класса

2. Указатель this инициализируется значением адреса объекта, для которого вызван метод, перед началом выполнения кода этого метода.

3. Имя this является служебным (ключевым) словом.

4. Явно описать или определить указатель this нельзя.

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

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

7. Внутри функции — члена класса можно явно исполь­зовать этот указатель.

 

Задание №1 для выполнения в классе

 

Конструктор копирования

Дывыдов, стр 49

Павловская 2 стр 171

Прата 602

Павловская 1 стр 184

Слабженников книга 2 стр 31

Глушаков, стр 14

Липман cnh 668

В Липмане есть примеры для шаблонов

 


Дата добавления: 2018-06-01; просмотров: 257; Мы поможем в написании вашей работы!

Поделиться с друзьями:




Мы поможем в написании ваших работ!