Рубрики

указатель 'this' в C ++

Чтобы понять указатель «this», важно знать, как объекты смотрят на функции и члены-данные класса.

  1. Каждый объект получает свою собственную копию элемента данных.
  2. Все доступ к тому же определению функции, что и в сегменте кода.

Это означает, что каждый объект получает свою собственную копию членов данных, и все объекты совместно используют одну копию функций-членов.
Тогда теперь возникает вопрос: если существует только одна копия каждой функции-члена и она используется несколькими объектами, как осуществляется доступ к соответствующим элементам данных и их обновление?
Компилятор предоставляет неявный указатель вместе с именами функций как «this».
Указатель 'this' передается как скрытый аргумент всем вызовам нестатических функций-членов и доступен как локальная переменная в теле всех нестатических функций. Указатель 'this' недоступен в статических функциях-членах, так как статические функции-члены могут вызываться без какого-либо объекта (с именем класса).
Для класса X тип этого указателя — «X *». Кроме того, если функция-член X объявлена как const, тогда тип этого указателя будет 'const X *' (см. Этот GFact )

В ранней версии C ++ указатель 'this' можно было бы изменить; тем самым программист может изменить объект, с которым работает метод. Эта функция была в конечном итоге удалена, и теперь это в C ++ является r-значением.
C ++ позволяет объектам уничтожать себя, вызывая следующий код:

delete this;

Как сказал Страуструп, «this» может быть ссылкой, а не указателем, но в ранней версии C ++ эта ссылка отсутствовала. Если «this» реализовано в качестве ссылки, вышеупомянутой проблемы можно избежать, и она может быть более безопасной, чем указатель.

Ниже приведены ситуации, в которых используется указатель this.

1) Когда имя локальной переменной совпадает с именем члена

#include<iostream>

using namespace std;

  
/ * локальная переменная совпадает с именем члена * /

class Test

{

private:

   int x;

public:

   void setX (int x)

   {

       // Указатель 'this' используется для получения объекта x

       // скрыт локальной переменной 'x'

       this->x = x;

   }

   void print() { cout << "x = " << x << endl; }

};

  

int main()

{

   Test obj;

   int x = 20;

   obj.setX(x);

   obj.print();

   return 0;

}

Выход:

 x = 20

Для конструкторов также можно использовать список инициализаторов, когда имя параметра совпадает с именем члена.

2) вернуть ссылку на вызывающий объект

/ * Ссылка на вызывающий объект может быть возвращена * / 
Test& Test::func ()
{

   // Некоторая обработка

   return *this;

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

#include<iostream>

using namespace std;

  

class Test

{

private:

  int x;

  int y;

public:

  Test(int x = 0, int y = 0) { this->x = x; this->y = y; }

  Test &setX(int a) { x = a; return *this; }

  Test &setY(int b) { y = b; return *this; }

  void print() { cout << "x = " << x << " y = " << y << endl; }

};

  

int main()

{

  Test obj1(5, 5);

  

  // Цепные вызовы функций. Все вызовы изменяют один и тот же объект

  // как тот же объект возвращается по ссылке

  obj1.setX(10).setY(20);

  

  obj1.print();

  return 0;

}

Выход:

x = 10 y = 20

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

Вопрос 1

#include<iostream>

using namespace std;

  

class Test

{

private:

  int x;

public:

  Test(int x = 0) { this->x = x; }

  void change(Test *t) { this = t; }

  void print() { cout << "x = " << x << endl; }

};

  

int main()

{

  Test obj(5);

  Test *ptr = new Test (10);

  obj.change(ptr);

  obj.print();

  return 0;

}

вопрос 2

#include<iostream>

using namespace std;

  

class Test

{

private:

  int x;

  int y;

public:

  Test(int x = 0, int y = 0) { this->x = x; this->y = y; }

  static void fun1() { cout << "Inside fun1()"; }

  static void fun2() { cout << "Inside fun2()"; this->fun1(); }

};

  

int main()

{

  Test obj;

  obj.fun2();

  return 0;

}

Вопрос 3

#include<iostream>

using namespace std;

  

class Test

{

private:

  int x;

  int y;

public:

  Test (int x = 0, int y = 0) { this->x = x; this->y = y; }

  Test setX(int a) { x = a; return *this; }

  Test setY(int b) { y = b; return *this; }

  void print() { cout << "x = " << x << " y = " << y << endl; }

};

  

int main()

{

  Test obj1;

  obj1.setX(10).setY(20);

  obj1.print();

  return 0;

}

Вопрос 4

#include<iostream>

using namespace std;

  

class Test

{

private:

  int x;

  int y;

public:

  Test(int x = 0, int y = 0) { this->x = x; this->y = y; }

  void setX(int a) { x = a; }

  void setY(int b) { y = b; }

  void destroy()  { delete this; }

  void print() { cout << "x = " << x << " y = " << y << endl; }

};

  

int main()

{

  Test obj;

  obj.destroy();

  obj.print();

  return 0;

}

Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.

Рекомендуемые посты:

указатель 'this' в C ++

0.00 (0%) 0 votes