В каких выражениях присутствует указатель ооп
Обновлено: 04.11.2024
Один из частых вопросов, которые новички задают по поводу классов: «При вызове метода класса, как C++ отслеживает то, какой объект его вызвал?». Ответ заключается в том, что C++ для этих целей использует скрытый указатель *this!
Оглавление:Скрытый указатель *this
Ниже приведен простой класс, который содержит целочисленное значение и имеет конструктор и функции доступа. Обратите внимание, деструктор здесь не нужен, так как язык C++ может очистить память после переменной-члена самостоятельно:
class Another private : int m_number ; public : Another ( int number ) setNumber ( number ) ; void setNumber ( int number ) < m_number = number ; > int getNumber ( ) < return m_number ; > int main ( ) Another another ( 3 ) ; another . setNumber ( 4 ) ; std :: cout << another . getNumber ( ) << '\n' ; return 0 ;Результат выполнения программы:
При вызове another.setNumber(4); C++ понимает, что функция setNumber() работает с объектом another , а m_number — это фактически another.m_number . Рассмотрим детально, как это всё работает.
Возьмем, к примеру, следующую строку:
another . setNumber ( 4 ) ;Хотя на первый взгляд кажется, что у нас здесь только один аргумент, но на самом деле у нас их два! Во время компиляции строка another.setNumber(4); конвертируется компилятором в следующее:
setNumber ( &another , 4 ) ; // объект another конвертировался из объекта, который находился перед точкой, в аргумент функции!Теперь это всего лишь стандартный вызов функции, а объект another (который ранее был отдельным объектом и находился перед точкой) теперь передается по адресу в качестве аргумента функции.
Но это только половина дела. Поскольку в вызове функции теперь есть два аргумента, то и метод нужно изменить соответствующим образом (чтобы он принимал два аргумента). Следовательно, следующий метод:
void setNumber ( int number ) < m_number = number ; >Конвертируется компилятором в:
void setNumber ( Another * const this , int number ) < this -> m_number = number ; >При компиляции обычного метода, компилятор неявно добавляет к нему параметр *this. Указатель *this — это скрытый константный указатель, содержащий адрес объекта, который вызывает метод класса.
Есть еще одна деталь. Внутри метода также необходимо обновить все члены класса (функции и переменные), чтобы они ссылались на объект, который вызывает этот метод. Это легко сделать, добавив префикс this-> к каждому из них. Таким образом, в теле функции setNumber(), m_number (переменная-член класса) будет конвертирована в this->m_number . И когда *this указывает на адрес another , то this->m_number будет указывать на another.m_number .
Соединяем всё вместе:
При вызове another.setNumber(4) компилятор фактически вызывает setNumber(&another, 4) .
Внутри setNumber() указатель *this содержит адрес объекта another .
К любым переменным-членам внутри setNumber() добавляется префикс this-> . Поэтому, когда мы говорим m_number = number , компилятор фактически выполняет this->m_number = number , который, в этом случае, обновляет another.m_number на number .
Хорошей новостью является то, что это всё происходит скрыто от нас (программистов), и не имеет значения, помните ли вы, как это работает или нет. Всё, что вам нужно запомнить — все обычные методы класса имеют указатель *this, который указывает на объект, связанный с вызовом метода класса.
Указатель *this всегда указывает на текущий объект
Начинающие программисты иногда путают, сколько указателей *this существует. Каждый метод имеет в качестве параметра указатель *this, который указывает на адрес объекта, с которым в данный момент выполняется операция, например:
Читайте также: