logo

вказівник «this» у C++

Щоб зрозуміти вказівник «this», важливо знати, як об’єкти виглядають на функції та члени даних класу.

  1. Кожен об’єкт отримує власну копію елемента даних.
  2. Повний доступ до того самого визначення функції, яке є в сегменті коду.

Це означає, що кожен об’єкт отримує власну копію членів даних, і всі об’єкти спільно використовують одну копію функцій-членів.
Тепер питання полягає в тому, що якщо існує лише одна копія кожної функції-члена та використовується декількома об’єктами, як здійснюється доступ до відповідних членів даних і як вони оновлюються?
Компілятор надає неявний покажчик разом із іменами функцій як «this».
Покажчик «this» передається як прихований аргумент для всіх викликів нестатичних функцій-членів і доступний як локальна змінна в тілі всіх нестатичних функцій.Покажчик «this» недоступний у статичних функціях-членах, оскільки статичні функції-члени можна викликати без жодного об’єкта (з назвою класу).
Для класу X тип цього вказівника – «X*». Крім того, якщо функцію-член X оголошено як const, тоді тип цього вказівника є «const X *» (див. цей GFact )



У ранній версії C++ можна було змінити покажчик «this»; завдяки цьому програміст міг змінити об’єкт, над яким працював метод. Зрештою цю функцію було видалено, і тепер це в C++ є значенням r.
C++ дозволяє об’єктам знищувати себе, викликаючи наступний код:




пошук bfs





delete> this>;>

>

>

Як сказав Страуструп, «це» може бути посиланням, ніж покажчиком, але посилання не було в ранній версії C++. Якщо «це» буде реалізовано як посилання, можна буде уникнути вищевказаної проблеми, і це буде безпечніше, ніж покажчик.

Нижче наведено ситуації, коли вказівник «цей» використовується:

1) Якщо ім’я локальної змінної збігається з ім’ям члена




#include> using> namespace> std;> > /* local variable is same as a member's name */> class> Test> {> private>:> >int> x;> public>:> >void> setX (>int> x)> >{> >// The 'this' pointer is used to retrieve the object's x> >// hidden by the local variable 'x'> >this>->х = х;> >}> >void> print() { cout <<>'x = '> << x << endl; }> };> > int> main()> {> >Test obj;> >int> x = 20;> >obj.setX(x);> >obj.print();> >return> 0;> }>

>

>

Вихід:

 x = 20>

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



2) Повернути посилання на об’єкт, що викликає




/* Reference to the calling object can be returned */> Test& Test::func ()> {> >// Some processing> >return> *>this>;> }>

>

>

Коли повертається посилання на локальний об’єкт, повернуте посилання можна використовувати для ланцюгові виклики функцій на одному об'єкті.




#include> using> namespace> std;> > class> Test> {> private>:> >int> x;> >int> y;> public>:> >Test(>int> x = 0,>int> y = 0) {>this>->х = х;>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);> > >// Chained function calls. All calls modify the same object> >// as the same object is returned by reference> >obj1.setX(10).setY(20);> > >obj1.print();> >return> 0;> }>

>

>

Вихід:

x = 10 y = 20>



Вправа:
Прогнозуйте вихід наступних програм. Якщо є помилки компіляції, виправте їх.

питання 1




#include> using> namespace> std;> > class> Test> {> private>:> >int> x;> public>:> >Test(>int> x = 0) {>this>->х = х; }> >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> using> namespace> std;> > class> Test> {> private>:> >int> x;> >int> y;> public>:> >Test(>int> x = 0,>int> y = 0) {>this>->х = х;>this>->y = y; }> >static> void> fun1() { cout <<>'Inside fun1()'>; }> >static> void> fun2() { cout <<>'Inside fun2()'>;>this>->весело1(); }> };> > int> main()> {> >Test obj;> >obj.fun2();> >return> 0;> }>

>

>



Питання 3




#include> using> namespace> std;> > class> Test> {> private>:> >int> x;> >int> y;> public>:> >Test (>int> x = 0,>int> y = 0) {>this>->х = х;>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> using> namespace> std;> > class> Test> {> private>:> >int> x;> >int> y;> public>:> >Test(>int> x = 0,>int> y = 0) {>this>->х = х;>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;> }>

>

>