Щоб зрозуміти вказівник «this», важливо знати, як об’єкти виглядають на функції та члени даних класу.
- Кожен об’єкт отримує власну копію елемента даних.
- Повний доступ до того самого визначення функції, яке є в сегменті коду.
Це означає, що кожен об’єкт отримує власну копію членів даних, і всі об’єкти спільно використовують одну копію функцій-членів.
Тепер питання полягає в тому, що якщо існує лише одна копія кожної функції-члена та використовується декількома об’єктами, як здійснюється доступ до відповідних членів даних і як вони оновлюються?
Компілятор надає неявний покажчик разом із іменами функцій як «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;> }> |
>
>