'tento' ukazovateľ v C++

Na pochopenie „tohto“ ukazovateľa je dôležité vedieť, ako sa objekty pozerajú na funkcie a dátové členy triedy.

  1. Každý objekt dostane svoju vlastnú kópiu dátového člena.
  2. Všeobecný prístup k rovnakej definícii funkcie ako v segmente kódu.

To znamená, že každý objekt dostane svoju vlastnú kópiu údajových členov a všetky objekty zdieľajú jednu kópiu členských funkcií.
Potom je teraz otázkou, že ak existuje iba jedna kópia každej členskej funkcie a používa ju viacero objektov, ako sa pristupuje k správnym dátovým členom a ako sa aktualizujú?
Kompilátor poskytuje implicitný ukazovateľ spolu s názvami funkcií ako „toto“.
Ukazovateľ „toto“ sa odovzdáva ako skrytý argument všetkým volaniam nestatických členských funkcií a je dostupný ako lokálna premenná v tele všetkých nestatických funkcií. Ukazovateľ „toto“ nie je dostupný v statických členských funkciách, pretože statické členské funkcie možno volať bez akéhokoľvek objektu (s názvom triedy).
Pre triedu X je typ tohto ukazovateľa „X*“. Tiež, ak je členská funkcia X deklarovaná ako const, potom typ tohto ukazovateľa je „const X *“ (pozri tento GFact )

V ranej verzii C++ by bolo možné zmeniť „tento“ ukazovateľ; tak by programátor mohol zmeniť objekt, na ktorom metóda pracuje. Táto funkcia bola nakoniec odstránená a teraz je to v C++ hodnota r.
C++ umožňuje objektom, aby sa zničili volaním nasledujúceho kódu:




delete> this> ;>

Ako povedal Stroustrup, „toto“ by mohol byť odkaz ako ukazovateľ, ale odkaz nebol prítomný v skorej verzii C++. Ak je „toto“ implementované ako referencia, vyššie uvedenému problému by sa dalo predísť a mohlo by to byť bezpečnejšie ako ukazovateľ.

Nasledujú situácie, keď sa používa „tento“ ukazovateľ:

1) Keď je názov lokálnej premennej rovnaký ako meno člena




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

Výkon:

 x = 20 

Pre konštruktérov, zoznam inicializátorov možno použiť aj vtedy, keď je názov parametra rovnaký ako meno člena.



2) Vráti odkaz na volajúci objekt




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

Keď sa vráti odkaz na lokálny objekt, vrátený odkaz sa dá použiť volania reťazových funkcií na jedinom objekte.




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

Výkon:

x = 10 y = 20 



Cvičenie:
Predpovedajte výstup nasledujúcich programov. Ak sa vyskytnú chyby pri kompilácii, opravte ich.

Otázka 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;> }>



Otázka 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> ->fun1(); }> };> > int> main()> {> > Test obj;> > obj.fun2();> > return> 0;> }>



Otázka 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;> }>



Otázka 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;> }>