C ++通过引用和这个对象传递

时间:2013-06-10 17:48:03

标签: c++ class reference this

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

5 个答案:

答案 0 :(得分:1)

因为成员函数隐式作为参数接收指向它所调用的对象的指针。该指针在函数体内作为this指针使用。

所以当你这样做时:

b->isitme(a)

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

由于b指向athis将指向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。在这种情况下,它是,所以好的