Шаг 11.
Указатель this

    На этом шаге мы рассмотрим назначение и использование указателя this.

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

   имя_класса::имя_компонентной_функции
   имя_класса   * const this = адрес_обрабатываемого_объекта;

    Имя this является служебным (ключевым) словом. Явно описать или определить указатель this нельзя. В соответствии с неявным определением this является константным указателем, т.е. изменять его нельзя, однако в каждой принадлежащей классу функции он указывает именно на тот объект, для которого функция вызывается. Говорят, что указатель this является дополнительным (скрытым) параметром каждой нестатической компонентной функции. Другими словами, при входе в тело принадлежащей классу функции указатель this инициализируется значением адреса того объекта, для которого вызвана функция. Объект, который адресуется указателем this, становится доступным внутри принадлежащей классу функции именно с помощью указателя this. При работе с компонентами класса внутри принадлежащей классу функции можно было бы везде использовать этот указатель. Например, совершенно правильным будет такое определение класса:

struct ss
{   int si;   
    char  sc;
    ss(int in, char en)   // Конструктор объектов класса.
    { this->si = in;   this->sc = en; }
    void print(void)      // Функция вывода сведений об объекте.
    { cout <<  "\n si = "  << this->si; 
      cout <<  "\n sc =  "  << this->se; }
};

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

//OOР11_1.СРР - указатель "this".
#include <iostream.h>
class cell	// Класс "числовой элемент".
{    
   int static Amount; // Общее количество элементов. 
   int Number;        // Порядковый номер элемента. 
   double Meaning;    // Значение элемента. 
  public:
  //Конструктор: 
  cell(double Meaning = 0.0)
  { // Меняем значение статического компонента: 
    Amount++;
    this -> Number = Amount; 
    // Компонент и одноименный параметр: 
    this -> Meaning = Meaning; }
    // Вывод сведений об объекте и количестве элементов: 
    void display (void)
    { 
    // Лишние this:
    cout << "\nNumber = " << this->Number; 
    cout << " Amount = " <<  this->Amount; 
    cout << " Meaning = " << this->Meaning;
  }
}; 
// Инициализация статического компонента:
int cell::Amount = 0;
void main(void)
{ cell A;	// Объект с умалчиваемым значением.
  A.display();
  cell B(200.0);
  cell C(300.0);
  B.display();
  C.display(); 
}
Текст этой программы можно взять здесь.

    Результат выполнения программы:

    Number = 1  Amount = 1  Meaning = 0 
    Number = 2  Amount = 3  Meaning = 200 
    Number = 3  Amount = 3  Meaning = 300

Почему во второй строке значение компонентного данного Amount равно 3, а не 2, как можно было предполагать?

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

    имя_класса::имя_компонента      .

    В приведенном примере класса cell конструктор может быть и таким:

   cell(double Meaning = 0.0) { 
      Amount++;
      Number = Amount;
      cell::Meaning = Meaning; // Устранение неоднозначности.
   }

    На следующем шаге мы продолжим изучение указателя this.




Предыдущий шаг Содержание Следующий шаг