0

为什么回答“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;
}
4

5 回答 5

1

简短的回答是b指向的指针a——它们都引用同一个实际对象,所以当你比较这“两个”对象的地址时,它们比较相等。

确实需要指出其他一些事情,虽然它的评论多于答案,但它不适合评论,所以......

int CTest::isitme(CTest &cobj)
{
    if(&cobj == this)
    {
        return true;
    }
    else
    {
        return false;
    }
}

老实说,这是非常糟糕的代码。既然它真的返回 a bool,你应该声明它返回一个布尔值。直接返回比较结果也更好。您还应该阅读一些有关“const 正确性”的内容。考虑到这些因素,您的函数最终看起来更像这样:

bool CTest::isitme(CTest const &cobj) const {
    return this == &cobj;
}
于 2013-06-10T17:53:37.613 回答
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检查将失败,因为它正在比较两个不同对象的指针(内存地址)。

于 2013-06-10T18:35:10.163 回答
1

因为成员函数隐式地接收一个指向调用它的对象的指针作为参数。该指针在函数体中作为this指针可用。

所以当你这样做时:

b->isitme(a)

成员函数isitme() 隐式接收指针b作为参数,并且该指针将被视为this函数内部的指针。

由于b指向a,this将指向a(毕竟,您是通过指针调用isitme()对象上的成员函数)。ab

由于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"

评估为true

于 2013-06-10T17:49:09.877 回答
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;        
}
于 2013-06-10T17:51:28.817 回答
0

b 指向 a,那么您正在使用 a in

b->isitme(a)

isitme() 只是检查作为参数传递的对象this。在这种情况下是这样,所以OK

于 2013-06-10T17:53:24.150 回答