'tento' ukazatel v C++
Abychom pochopili „toto“ ukazatel, je důležité vědět, jak se objekty dívají na funkce a datové členy třídy.
- Každý objekt získá svou vlastní kopii datového členu.
- All-access stejná definice funkce, jaká je přítomna v segmentu kódu.
To znamená, že každý objekt získá svou vlastní kopii datových členů a všechny objekty sdílejí jednu kopii členských funkcí.
Nyní je otázkou, že pokud existuje pouze jedna kopie každé členské funkce a je používána více objekty, jak jsou správné datové členy přístupné a aktualizovány?
Kompilátor dodává implicitní ukazatel spolu s názvy funkcí jako „toto“.
Ukazatel „toto“ je předán jako skrytý argument všem voláním nestatických členských funkcí a je dostupný jako lokální proměnná v těle všech nestatických funkcí. Ukazatel „toto“ není k dispozici ve statických členských funkcích, protože statické členské funkce lze volat bez jakéhokoli objektu (s názvem třídy).
Pro třídu X je typ tohoto ukazatele ‚X*‘. Také, pokud je členská funkce X deklarována jako const, pak typ tohoto ukazatele je „const X *“ (viz tento GFact )
V rané verzi C++ by bylo možné změnit ukazatel „toto“; tak mohl programátor změnit objekt, na kterém metoda pracovala. Tato funkce byla nakonec odstraněna a nyní je to v C++ hodnota r.
C++ umožňuje, aby se objekt sám zničil voláním následujícího kódu:
delete> this> ;> |
Jak řekl Stroustrup, „toto“ by mohl být odkaz než ukazatel, ale odkaz nebyl přítomen v rané verzi C++. Pokud je „toto“ implementováno jako reference, lze se výše uvedenému problému vyhnout a mohlo by to být bezpečnější než ukazatel.
Následují situace, kdy je použit ukazatel „toto“:
1) Když je název lokální proměnné stejný jako jméno č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ýstup:
x = 20
Pro konstruktéry, seznam inicializátorů lze také použít, když je název parametru stejný jako jméno člena.
2) Vrátit odkaz na volající objekt
/* Reference to the calling object can be returned */> Test& Test::func ()> {> > // Some processing> > return> *> this> ;> }> |
Když je vrácen odkaz na místní objekt, lze vrácený odkaz použít volání řetězových funkcí na jediném objektu.
#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ýstup:
x = 10 y = 20
Cvičení:
Předvídejte výstup následujících programů. Pokud se vyskytnou chyby při kompilaci, opravte je.
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;> }> |