logo

wskaźnik „ten” w C++

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

model protokołu TCP i IP
  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>;> }>

>

>

ciąg java

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


k najbliższy sąsiad



#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




ciąg do znaku

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

>

>