为什么回答“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;
}
答案 0 :(得分:1)
因为成员函数隐式作为参数接收指向它所调用的对象的指针。该指针在函数体内作为this
指针使用。
所以当你这样做时:
b->isitme(a)
成员函数isitme()
隐式接收指针b
作为参数,该指针将被视为函数内的this
指针。
由于b
指向a
,this
将指向a
(毕竟,您正在对象{{1}上调用成员函数isitme()
通过指针a
)。
由于b
是作为显式参数传递的内容,a
也是引用a
绑定的内容。因此,使用cobj
的地址会为您提供cobj
的地址。这反过来意味着,表达式:
a
评估为// 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"
。
答案 1 :(得分:1)
简短的回答是b
是指向a
的指针 - 它们都引用相同的实际对象,因此当您比较这些“两个”对象的地址时,它们会比较相等。 / p>
还有其他一些事情需要指出,虽然它的评论多于答案,但它不适合评论,所以......
int CTest::isitme(CTest &cobj)
{
if(&cobj == this)
{
return true;
}
else
{
return false;
}
}
老实说,这是非常糟糕的代码。因为它确实返回了bool
,所以你应该声明它返回一个bool。直接从比较中返回结果也要好得多。您还应该阅读一些关于“const正确性”的内容。考虑到这些因素,您的功能最终看起来更像是这样:
bool CTest::isitme(CTest const &cobj) const {
return this == &cobj;
}
答案 2 :(得分:1)
这里有几件事情。
首先,只分配了一份CTest
副本。要检查这一点,您可以在构造函数中放置一个打印:
class CTest {
public:
CTest() {
cout << "Constructor called";
}
...
};
如果您随后调用了程序,则会看到构造函数只被调用一次。
调用isitme
时,this
指针将与cobj
参数的地址进行比较。两者都指向同一个对象,因此它们都包含相同的内存地址。因此,比较过去了。
要注意的另一件事是你通过参考传递。如果你没有通过引用传递,那么这将无效。例如,如果您有以下代码:
class CTest {
public:
...
bool isitme(CTest cobj) {
return this == &cobj;
}
};
然后该对象将按值传递。结果,制作了cobj
的副本。实际上,调用另一个构造函数(编译器提供的默认复制构造函数)来创建一个新对象,该对象是给定对象的副本。
要证明这一点,请覆盖默认的复制构造函数以显示消息。
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;
...
}
现在,如果你运行程序,你会发现两个构造函数都被调用了。第一次是a
的构造函数。第二次是将a
传递给isitme
方法并创建副本。
当按值传递时,isitme
检查会失败,因为它正在比较两个不同对象的指针(内存地址)。
答案 3 :(得分:0)
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;
}
答案 4 :(得分:0)
b指向a,然后你正在使用in
b->isitme(a)
isitme()只是检查作为参数传递的对象this
。在这种情况下,它是,所以好的