MySQL Java JavaScript PHP Python HTML-CSS C-sharp C++ Go

Cuvântul cheie this

Cuvântul cheie this reprezintă un pointer către obiectul curent al clasei date. Astfel, prin this putem accesa în interiorul clasei orice membru al acesteia.

#include <iostream>
 
class Point
{
public:
    Point(int x, int y)
    {
        this->x = x; 
        this->y = y;
    }
    void showCoords() 
    {
        std::cout << "Point x: " << this->x << "\t y: " << y << std::endl;
    }
private:
    int x;
    int y;
};
 
int main()
{
    Point p1{20, 50};
    p1.showCoords();
}

În acest caz este definită clasa Point, care reprezintă un punct în plan. Iar pentru stocarea coordonatelor punctului în clasă sunt definite variabilele x și y.

Pentru a accesa variabilele se folosește pointerul this. Iar după this se pune nu punctul, ci săgeata ->.

În majoritatea cazurilor, pentru a accesa membrii clasei nu este nevoie de cuvântul cheie this. Dar poate fi necesar dacă parametrii funcției sau variabilele definite în interiorul funcției se numesc la fel ca variabilele clasei. De exemplu, în constructor, pentru a distinge între parametri și variabilele clasei, se folosește pointerul this.

O altă utilizare practică a lui this – cu ajutorul lui putem returna obiectul curent al clasei:

#include <iostream>
 
class Point
{
public:
    Point(int x, int y)
    {
        this->x = x; 
        this->y = y;
    }
    void showCoords() 
    {
        std::cout << "Coords x: " << x << "\t y: " << y << std::endl;
    }
    Point &move(int x, int y)
    {
        this->x += x;
        this->y += y;
        return *this;
    }
private:
    int x;
    int y;
};
 
int main()
{
    Point p1{20, 50};
    p1.showCoords();    // Point x: 20  y: 50
    p1.move(10, 5).move(10, 10);
    p1.showCoords();    // Point x: 40  y: 65
}

Aici metoda move, cu ajutorul pointerului this, returnează o referință la obiectul curent al clasei, realizând o deplasare fictivă a punctului. Astfel, putem apela în lanț metoda move pentru același obiect:

p1.move(10, 5).move(10);

Aici este important să menționăm că se returnează nu pur și simplu un obiect Point, ci o referință la acest obiect. Astfel, linia de mai sus este echivalentă cu următorul cod:

p1.move(10, 5);
p1.move(10, 10);

Dar dacă metoda move ar fi returnat nu o referință, ci pur și simplu un obiect:

Point move(int x, int y)
{
    this->x += x;
    this->y += y;
    return *this;
}

Atunci apelul p1.move(10, 5).move(10) ar fi fost de fapt echivalent cu următorul cod:

Point temp = p1.move(10, 5);
temp.move(10, 10);

În care al doilea apel al metodei move s-ar fi executat pentru o copie temporară și nu ar fi afectat variabila p1.

Ca alternativă, putem returna pointerul this:

#include <iostream>
  
class Point
{
public:
    Point(int x, int y)
    {
        this->x = x; 
        this->y = y;
    }
    void showCoords() 
    {
        std::cout << "Point x: " << this->x << "\t y: " << y << std::endl;
    }
    Point* move(int x, int y)
    {
        this->x += x;
        this->y += y;
        return this;
    }
private:
    int x;
    int y;
};
  
int main()
{
    Point p1{20, 50};
    p1.showCoords();    // Point x: 20  y: 50
    p1.move(10, 5)->move(10, 10)->move(10, 15);
    p1.showCoords();    // Point x: 50  y: 80
}

În acest caz, deoarece funcția move() returnează pointerul this, putem apela din nou metoda move asupra rezultatului funcției folosind operatorul ->:

p1.move(10, 5)->move(10, 10)->move(10, 15)

Alt exemplu:

#include <iostream>
 
class Integer
{
public:
    Integer(int number)
    {
        value = number;
    }
    Integer& add(const Integer& obj)
    { 
        value += obj.value;
        return *this;
    }
 
    Integer& subtract(const Integer& obj) 
    {
        value -= obj.value;
        return *this;
    }
 
    Integer& multiply(const Integer& obj) 
    {
        value *= obj.value;
        return *this;
    }
     
    void print() const
    {
        std::cout << "Value: " << value << std::endl;
    }
private:
    int value;
};
int main()
{
    Integer num{10};
    num.add(Integer{30}).subtract(Integer{15}).multiply(Integer{2});
    num.print();    // Value: 50
}

Aici clasa Integer reprezintă convențional un număr întreg, care este stocat în variabila value. În ea sunt definite funcțiile add() (adunare), subtract() (scădere) și multiply() (înmulțire), care primesc un alt obiect Integer și efectuează operația corespunzătoare între obiectul curent și argument. Fiecare dintre aceste funcții returnează obiectul curent, datorită căruia aceste funcții pot fi apelate în lanț:

Integer num{10};
num.add(Integer{30}).subtract(Integer{15}).multiply(Integer{2});