wskaźnik „ten” w C++

Aby zrozumieć „ten” wskaźnik, ważne jest, aby wiedzieć, jak obiekty patrzą na funkcje i elementy danych klasy.

  1. Każdy obiekt otrzymuje własną kopię elementu danych.
  2. Dostęp dla wszystkich do tej samej definicji funkcji, jaka jest obecna w segmencie kodu.

Oznacza to, że każdy obiekt otrzymuje własną kopię elementów danych, a wszystkie obiekty korzystają z jednej kopii funkcji składowych.
Zatem teraz pytanie brzmi: jeśli istnieje tylko jedna kopia każdej funkcji składowej i jest używana przez wiele obiektów, w jaki sposób uzyskuje się dostęp do odpowiednich składowych danych i je je aktualizuje?
Kompilator dostarcza ukryty wskaźnik wraz z nazwami funkcji jako „to”.
Wskaźnik „this” jest przekazywany jako ukryty argument do wszystkich niestatycznych wywołań funkcji składowych i jest dostępny jako zmienna lokalna w treści wszystkich funkcji niestatycznych. Wskaźnik „this” nie jest dostępny w statycznych funkcjach składowych, ponieważ statyczne funkcje składowe można wywoływać bez żadnego obiektu (z nazwą klasy).
Dla klasy X typem tego wskaźnika jest „X*”. Ponadto, jeśli funkcja składowa X jest zadeklarowana jako const, wówczas typem tego wskaźnika jest „const X *” (zobacz ten GFact )

We wczesnej wersji C++ można było zmienić „ten” wskaźnik; w ten sposób programista może zmienić obiekt, nad którym pracuje dana metoda. Ta funkcja została ostatecznie usunięta i teraz w C++ jest to wartość r.
C++ pozwala obiektom zniszczyć się, wywołując następujący kod:




delete> this> ;>

Jak powiedział Stroustrup, „to” może być odniesieniem, a nie wskaźnikiem, ale odniesienia nie było we wczesnej wersji C++. Jeśli „to” zostanie zaimplementowane jako odniesienie, można uniknąć powyższego problemu i może być bezpieczniejsze niż wskaźnik.

Poniżej przedstawiono sytuacje, w których używany jest wskaźnik „ten”:

1) Gdy nazwa zmiennej lokalnej jest taka sama jak nazwa elementu




#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> ->x = x;> > }> > void> print() { cout < <> 'x = '> < < x < < endl; }> };> > int> main()> {> > Test obj;> > int> x = 20;> > obj.setX(x);> > obj.print();> > return> 0;> }>

Wyjście:

 x = 20 

Dla konstruktorów lista inicjatorów można również użyć, gdy nazwa parametru jest taka sama jak nazwa elementu.



2) Aby zwrócić referencję do obiektu wywołującego




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

Kiedy zwracane jest odwołanie do obiektu lokalnego, można wykorzystać zwrócone odwołanie wywołania funkcji łańcuchowych na jednym obiekcie.




#include> 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);> > > // 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;> }>

Wyjście:

x = 10 y = 20 



Ćwiczenia:
Przewiduj wyjście następujących programów. Jeśli występują błędy kompilacji, napraw je.

Pytanie 1




#include> 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;> }>



pytanie 2




#include> 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> ->zabawa1(); }> };> > int> main()> {> > Test obj;> > obj.fun2();> > return> 0;> }>



pytanie 3




#include> 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;> }>



Pytanie 4




#include> 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;> }>