c++通过引用和此对象传递
C++ pass by reference and this object
为什么答案是"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;
}
因为成员函数隐式地接收一个指向调用它的对象的指针作为实参。该指针在函数体中作为this
指针可用。
所以当你这样做的时候:
b->isitme(a)
成员函数isitme()
隐式地接收指针b
作为参数,该指针将被视为函数内部的this
指针。
由于b
指向a
,因此this
将指向a
(毕竟,您是通过指针b
在对象a
上调用成员函数isitme()
)。
由于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
简短的回答是b
是一个指向a
的指针——它们都指向同一个实际对象,所以当你比较这"两个"对象的地址时,它们比较起来是相等的。
还有一些东西确实需要指出,虽然它更像是评论而不是回答,但它不适合放在评论中,所以…
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;
}
这里有两件事。
首先,只分配了一个CTest
副本。要检查这一点,可以在构造函数中输入print:
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
检查将失败,因为它比较的是两个不同对象的指针(内存地址)
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;
}
b指向a,则在
中使用ab->isitme(a)
isitme()只是根据this
检查作为参数传递的对象。在本例中是OK
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- 我们可以有一个 setter 成员函数作为从 const 对象引用的 const 吗?
- C++对象引用返回不同的值
- 对象引用中的字段以不同的方法返回不同的值
- 通过向构造函数其他对象引用页面来创建对象
- 为什么在对象引用恒定时允许更改为另一个类的指针的成员变量
- 如何在C++中读取 HDF5 对象引用
- C++ 未定义的对象引用
- 从函数返回 libconfig 类设置对象引用
- qt vsaddin错误对象引用未设置为对象的istanse
- 在这种情况下,为什么使用 *此必需的对象引用返回对象引用
- 基本C - 构造contaning对象引用,并将其作为方法参数传递
- C :将对象引用作为参数给出错误:呼叫class :: function()的匹配函数
- C++OOP基础知识-是否正确返回对象引用
- 使用对象引用(可能)在调用destructor后使用对象引用
- 创建返回对象引用的成员函数的最简单方法
- 如何在C++上使用对象引用删除对象
- JNI/Android NDK-维护全局对象引用
- 为什么有些类方法返回"*this"(self的对象引用)?
- 在C++中返回伪对象引用的规则