'this' keyword used in class and objects is a constant pointer?

562 Views Asked by At

This question came in my mind due to the following error in my c++ program

#include <iostream>
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(15);
  Test *ptr = new Test (100);
  obj.change(ptr);
  obj.print();
  return 0;
}

Error:

main.cpp:18:31: error: lvalue required as left operand of assignment
   18 | void change(Test *t) { this = t; }
      |    

I searched about this error and found that it generally occurs when we try to assign the constants on the left hand side of the assignment operators to the variable on the right hand side.

3

There are 3 best solutions below

10
user12002570 On BEST ANSWER

According to 9.3.2 The this pointer [class.this]

1 In the body of a non-static (9.3) member function, the keyword this is a prvalue expression whose value is the address of the object for which the function is called. [...]

So as the error says, the left hand side should be an lvalue but you're giving it a prvalue because change is a non-static member function and inside any non-static member function the keyword this is a prvalue according to the above quoted statement. Hence the error.

But you can modify the object that this points to, as shown below:

#include <iostream>
using namespace std;
class Test
{
private:
  int x;
public:
  Test(int x = 0) { this->x = x; }
  void change(Test *t) { *this = *t; }//THIS WORKS 
  void print() { cout << "x = " << x << endl; }
};

int main()
{
  Test obj(15);
  Test *ptr = new Test (100);
  obj.change(ptr);
  obj.print();
  return 0;
}

Note in the above example i have replaced this = t; with

*this = *t;//this time it works because now the left hand side is an lvalue 

This time the program works because now the left hand side is an lvalue.

Some More Explanation

From IBM's this pointer documentation,

The this parameter has the type Test *const. That is, it is a constant pointer to a Test object. Now since it is constant pointer, you cannot assign a different pointer value to it using this = t;. And hence the error.

Similarly, from Microsoft's this pointer documentation,

the this pointer is always a const pointer. It can't be reassigned.

So this also explains the error you're getting.

0
Ch3steR On

From cppreference this:

The keyword this is a prvalue expression whose value is the address of the implicit object parameter (object on which the non-static member function is being called).

You can't assign to rvalues(e.g. 1 = obj is invalid). So, you'd have to dereference this and assign.

*this = *t;

To answer the title of the question,

this keyword used in class and objects is a constant pointer?

No, it is not. Even if a member function is marked const then it's still a pointer to const object.

From cppereference,

The type of this in a member function of class X is X* (pointer to X). If the member function is cv-qualified, the type of this is cv X* (pointer to identically cv-qualified X).

10
Keanyuan On

In non-const member function, the type of this is "Type* const this" while it is "const Type* const this" in const member function. So you can't change a const this value to make it point to another address. you can use codes below to simulate it :

struct A{
    int a;
};
int main() {
      A* const p = new A();
      p = new A();    
      return 0;
}

you will get the same errorenter image description here

The following pictures shows the types of this in const member function and non-const member function: enter image description here

enter image description here