Ключевое слово this

Последнее обновление: 10.03.2023

Ключевое слово this представляет указатель на текущий объект данного класса. Соответственно через 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;
	}
private:
	int x;
	int y;
};

int main()
{
	Point p1{20, 50};
	p1.showCoords();
}

В данном случае определен класс Point, который представляет точку на плоскости. И для хранения координат точки в классе определены переменные x и y.

Для обращения к переменным используется указатель this. Причем после this ставится не точка, а стрелка ->.

В большинстве случаев для обращения к членам класса вряд ли поднадобится ключевое слово this. Но оно может быть необходимо, если параметры функции или переменные, которые определяются внутри функции, называются также как и переменные класса. К примеру, чтобы в конструкторе разграничить параметры и переменные класса как раз и используется указатель this.

Другое практическое применение this - с его помощью можно возвращать текущий объект класса:

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

Здесь метод move с помощью указателя this возвращает ссылку на объект текущего класса, осуществляя условное перемещение точки. Таким образом, мы можем по цепочке для одного и того же объекта вызывать метод move:

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

Здесь также важно отметить возвращение не просто объекта Point, а ссылки на этот объект. Так, в данном случае выге определенная строка фактически будет аналогично следующему коду:

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

Но если бы метод move возвращал бы не ссылку, а посто объект:

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

То вызов p1.move(10, 5).move(10) был бы фактически эквивалентен следующему коду:

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

Где второй вызов метода move вызывался бы для временной копии и никак бы не затрагивал переменную p1.

В качестве альтернативы можно возвращать сам указатель 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
}

В данном случае, поскольку функция move() возвращает указатель this, то у результата функции мы также можем вызвать функцию move через операцию ->:

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

Другой пример:

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

Здесь класс Integer представляет условно целое число, которое хранится в переменной value. В нем определены функции add() (сложение), subtract() (вычитание), и multiply() (умножение), которые принимают другой объект Integer и выполняеют соответствующую операцию между текущим объектом и аргументом. Причем каждая из этих функций возвращает текущий объект, благодаря чему эти функции можно было выполнить по цепочке:

Integer num{10};
num.add(Integer{30}).subtract(Integer{15}).multiply(Integer{2});
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850