Reputation: 3423
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
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
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
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
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