AvinashK
AvinashK

Reputation: 3423

How does "this" pointer happen to point to different objects?

Suppose I have a class:

class test {
public:
   void print();
private:
   int x;
};

void test::print()  
{  
    cout<< this->x;  
}

and I have these variable definitions:

test object1;
test object2;

When I call object1.print() this happens to store address of object1 and so I get x from object1 printed and when I call object2.print() this happens to store address of object2 and I get x from object2 printed. How does it happen?

Upvotes: 1

Views: 1049

Answers (5)

Frerich Raabe
Frerich Raabe

Reputation: 94329

You can think of the this pointer being an implicit argument to the functions. Imagine a little class like

class C {
public:
  C( int x ) : m_x( x ) { }

  void increment( int value ) {
    m_x += value; // same as 'this->m_x += value'
  }

  int multiply( int times ) const {
    return m_x * times; // same as 'return this->m_x * times;'
  }

private:
  int m_x;
};

which allows you to write code like

C two( 2 );
two.increment( 2 );
int result = two.multiply( 3 );

Now, what's actually happening is that the member functions increment and multiply are called with an extra pointer argument, pointing to the object on which the function is invoked. This pointer is known as this inside the method. The type of the this pointer is different, depending on whether the method is const (as multiply is) or not (as is the case with increment).

You can do something like it yourself as well, consider:

class C {
public:
  C( int x ) : m_x( x ) { }

  void increment( C * const that, int value ) {
    that->m_x += value;
  }

  int multiply( C const * const that, int times ) const {
    return that->m_x * times;
  }

private:
  int m_x;
};

you could write code like

C two( 2 );
two.increment( &two, 2 );
int result = two.multiply( &two, 3 );

Notice that the type of the this pointer is C const * const for the multiply function, so both the pointer itself is const but also the object being pointed to! This is why you cannot change member variables inside a const method - the this pointer has a type which forbids it. This could be resolved using the mutable keyword (I don't want to get side-tracked too far, so I'll rather not explain how that works) but even using a const_cast:

int C::multiply( int times ) const {
  C * const that = const_cast<C * const>( this );
  that->m_x = 0; // evil! Can modify member variable because const'ness was casted away
  // ..
}

I'm mentioning this since it demonstrates that this isn't as special a pointer as it may seem, and this particular hack is often a better solution than making a member variable mutable since this hack is local to one function whereas mutable makes the variable mutable for all const methods of the class.

Upvotes: 2

sharptooth
sharptooth

Reputation: 170489

Each non-static member function has an implicit hidden "current object" parameter that is exposed to you as this pointer.

So you can think that for

test::print();

there's some

test_print( test* this );

global function and so when you write

objectX.print();

in your code the compiler inserts a call to

test_print(&objectX);

and this way the member function knows the address of "the current" object.

Upvotes: 6

C.J.
C.J.

Reputation: 16091

Each instance of class test gets it's own copy of member variable x. Since x is unique for each instance, the value can be anything you want it to be. The variable this, refers to the instance to which it is associated. You don't have to use the variable 'this'. You could just write:

void test::print()
{
   cout << x;
}

Upvotes: 1

rmflow
rmflow

Reputation: 4775

this has different values for different objects

Upvotes: 1

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272517

The way to think about it is that this is simply a pointer to the memory for whichever object you're currently working with. So if you do obj1.print(), then this = &obj1;. If you do obj2.print(), then this = &obj2;.

Upvotes: 1

Related Questions