За одним исключением, рассматриваемым в разделе 7.6, вызов функции-члена осуществляется от имени объекта. Когда функция isbn()
обращается к члену класса Sales_data
(например, bookNo
), она неявно обращается к членам того объекта, из которого была вызвана. В этом вызове функции isbn()
, когда она возвращает значение члена bookNo
, речь идет о члене total.bookNo
.
Функция-член способна обратиться к тому объекту, из которого она была вызвана, благодаря дополнительному неявному параметру this
инициализируется адресом объекта, из которого была вызвана функция. Рассмотрим следующий вызов:
total.isbn()
Здесь компилятор присваивает адрес объекта total
указателю this
и неявно передает его как параметр функции isbn()
. Компилятор как бы переписывает этот вызов так:
//
Sales_data::isbn(&total)
Этот код вызывает функцию-член isbn()
класса Sales_data
, передав адрес объекта total
.
В функции-члене можно обратиться непосредственно к членам объекта, из которого она была вызвана. Для использования членов объекта, на который указывает указатель this
, можно не использовать оператор доступа к члену. Любое непосредственное использование члена класса подразумевает использование указателя this
. Таким образом, когда функция isbn()
использует переменную bookNo
, она неявно использует член объекта, на который указывает указатель this
. Это аналогично синтаксису this->bookNo
.
Параметр this
определяется неявно и автоматически. Кроме того, определить параметр или переменную по имени this
самому нельзя, но в теле функции-члена его использовать можно. Вполне допустимо, хоть и не нужно, определить функцию isbn()
так:
std::string isbn() const { return this->bookNo; }
Поскольку указатель this
всегда предназначен для обращения к "этому" объекту, он является константным (см. раздел 2.4.2). Нельзя изменить адрес, хранящийся в указателе this
.
Еще одним важным моментом функции-члена isbn()
является ключевое слово const
, расположенное за списком параметров. Оно применяется для модификации типа неявного указателя this
.
По умолчанию указатель this
имеет тип константного указателя на неконстантную версию типа класса. Например, типом по умолчанию указателя this
в функции-члене Sales_data
является Sales_data *const
. Хоть указатель this
и неявен, он подчиняется обычным правилам инициализации, согласно которым (по умолчанию) нельзя связать указатель this
с константным объектом (см. раздел 2.4.2). Следствием этого факта, в свою очередь, является невозможность вызвать обычную функцию-член для константного объекта.
Если бы функция isbn()
была обычной и если бы указатель this
был обычным параметром типа указателя, то мы объявили бы его как const Sales_data *const
. В конце концов, тело функции isbn()
не изменяет объект, на который указывает указатель this
; таким образом, эта функция стала бы гибче, если бы указатель this
был указателем на константу (см. раздел 6.2.3).
Однако указатель this неявный и не присутствует в списке параметров, поэтому нет места, где можно было бы указать, что он должен быть указателем на константу. Язык решает эту проблему, позволяя разместить ключевое слово const
после списка параметров функции-члена. Это означает, что указатель this
является указателем на константу. Функции-члены, использующие ключевое слово const
таким образом, являются
Тело функции isbn()
можно считать написанным так:
//
//
//
//
std::string Sales_data::isbn(const Sales_data *const this)
{ return this->isbn; }
Тот факт, что this
является указателем на константу, означает, что константные функции-члены не могут изменить объект, для которого они вызваны. Таким образом, функция isbn()
может читать значения переменных- членов объектов, для которых она вызывается, но не изменять их.