Reputation: 7161
Why is answer "OK"?
class CTest {
public:
int isitme(CTest& cobj);
};
int CTest::isitme(CTest &cobj)
{
if(&cobj == this)
{
return true;
}
else
{
return false;
}
}
int main()
{
CTest a;
CTest *b = &a;
if(b->isitme(a))
{
cout<<"OK";
}else
{
cout<<"not OK";
}
return 0;
}
Upvotes: 0
Views: 128
Reputation: 2063
There are a couple of things going on here.
First, there is only one copy of CTest
being allocated. To check this, you could put a print in the constructor:
class CTest {
public:
CTest() {
cout << "Constructor called";
}
...
};
If you then invoked your program, you'd see that the constructor was called only once.
When isitme
is invoked, the this
pointer is being compared to the address of the cobj
parameter. Both are pointing to the same object, so they both contain the same memory address. Thus, the comparison passes.
The other thing to notice is that you are passing by reference. If you didn't pass by reference, then this would not work. For example, if you had the following code:
class CTest {
public:
...
bool isitme(CTest cobj) {
return this == &cobj;
}
};
Then the object would be passed by value. As a result, a copy of cobj
is made. In fact, another constructor (the compiler provided default copy constructor) is called to make a new object which is a copy of the given one.
To prove this, override the default copy constructor to display a message.
class CTest {
public:
// Default constructor
CTest() {
cout << "Constructor called" << endl;
}
// Copy constructor
CTest(CTest& source) {
cout << "Copy constructor called" << endl;
}
// Comparison
bool isitme(CTest obj) {
return (this == &obj);
}
};
// Main program
int main (int argc, char* argv[]) {
...
CTest a;
CTest* b = &a;
cout << (b->isitme(a)) << endl;
...
}
Now if you run the program, you'd notice both constructors are called. The first time is during the constructor for a
. The second time is when you pass a
to the isitme
method and it creates a copy.
When passed by value, the isitme
check would fail because it is comparing the pointers (memory addresses) of two different objects.
Upvotes: 1
Reputation: 490048
The short answer is that b
is a pointer to a
-- they both refer to the same actual object, so when you compare those "two" objects' addresses, they compare equal.
There's something else that really needs to be pointed out, and although it's more comment than answer, it won't fit in a comment, so...
int CTest::isitme(CTest &cobj)
{
if(&cobj == this)
{
return true;
}
else
{
return false;
}
}
This is, quite honestly, pretty lousy code. Since it's really returning a bool
, you should declare it to return a bool. It's also much better to directly return the result from the comparison. You should also do some reading about "const correctness". Taking those factors into account, your function ends up looking more like this:
bool CTest::isitme(CTest const &cobj) const {
return this == &cobj;
}
Upvotes: 1
Reputation: 126412
Because a member function implicitly receives as an argument a pointer to the object it is invoked on. This pointer is made available within the body of the function as the this
pointer.
So when you do:
b->isitme(a)
The member function isitme()
implicitly receives the pointer b
as an argument, and that pointer will be seen as the this
pointer inside the function.
Since b
points to a
, this
will point to a
(after all, you are invoking the member function isitme()
on object a
through the pointer b
).
Since a
is what is being passed as an explicit argument, a
is also what the reference cobj
is bound to. Therefore, taking the address of cobj
gives you the address of a
. Which in turns mean, that the expression:
// Address of "a": "cobj" is bound to argument "a" in the function call
// vvvvv
&cobj == this
// ^^^^
// Address of "a": the function is called through a pointer to "a"
Evaluates to true
.
Upvotes: 1
Reputation: 532
b is pointing a, then you are using a in
b->isitme(a)
the isitme() simply checks the object passed as parameter against this
. In this case it is, so OK
Upvotes: 0
Reputation: 1423
int CTest::isitme(CTest &cobj)
{
// cobj is a reference, but still an object
CTest * pCobj = &cobj; //pCobj is now the pointer to the actual memory
//so it's the same as this pointer. Because you did before CTest *b = &a;
}
Upvotes: 0