我正在开发一个C ++程序,在调试时我正在使用以下函数:
int CClass::do_something()
{
... // I've put a breakpoint here
}
我的CClass
有一个属性,我们称之为att
。
当我的程序在断点处暂停时,我在Watch窗口中放了三个东西:
att
this->att
this.att
前两个att
和this->att
包含正确的值,但this.att
包含错误的值(至少看起来不对)。
它显示价值的事实意味着this.att
具有某种意义。
那是什么意思?与this.att
相比,this->att
的含义是什么?
为了您的信息,我使用Visual Studio作为开发环境。
答案 0 :(得分:2)
箭头运算符->
在左侧的pointer上运行,这意味着它访问左侧指针指向的运算符。正如许多其他地方所指出的,->
运算符是手动解除引用指针和使用点表示法的简写。 a->b == (*a).b
。这意味着它需要查找的上下文信息,它可以通过指针值找到。点运算符.
假设您对左侧的对象有引用,因此不需要首先取消引用其左侧的指针。
如果您的调试器以某种方式允许您使用点运算符而不是箭头运算符,可能因为它没有(或不能)验证使用的类型,它将假定指针变量的地址,而不是由值指向的地址持有的地址是对象。
换句话说,它将查看内存中某个对象本身的对象。行为很可能是未定义的,您只会看到实际存储在成员att
的内存偏移处的垃圾数据。
假设您的对象已布局,以便属性foo
位于偏移0处,属性att
位于偏移量4处,则调试器基本上会查看对象实例的地址加上你的成员变量所持有的任何偏移我不在我的家用电脑上,但我可以添加一个草图,说明稍后会澄清一些事情。
答案 1 :(得分:0)
att
本身返回该类实例的成员变量att
。
this->att
返回与att
相同的内容,只是this->
明确告诉程序返回类的att
成员变量。
att
和this->att
返回不同值的情况示例是在类中的本地范围内重新定义att
的情况。在这种情况下,att
将引用本地定义的att
,而this->att
将引用该类的att
成员变量。
由于this
是指向当前对象的指针,因此它需要->
表示法(这是取消引用指针和成员/方法访问权限的组合)。 .
表示法仅是成员/方法访问权限。要回答你的问题" this.att
"的含义是什么,我会说这是毫无意义的,说实话,我很惊讶甚至根本没有回复任何东西。
唯一的#34;权利"你可以this
与.
一起使用的方法是先取消引用指针,如下所示:
(*this).att
但是,如果您只使用->
,结果是相同的,语法是相同的。
答案 2 :(得分:0)
好的,只是在没有进一步信息的情况下盲目猜测,但让我尝试了解您在调试器中看到的内容,因为这是您的问题吗?因此,我不会解释.
和->
之间的区别。假设以下情况:
class CClass
{
int x; // at offset 0 of CClass
int att; // at offset 4 of CClass
};
CClass* p = // ... (say p points to the address 0xF0 for now)
int CClass::do_something
{
CClass q;
CClass* r;
}
因此,现在检查调试器中表达式p->att
的值,调试器所做的是取值p
(此处为0xF0
)并添加{{{}的偏移量1}}到它,导致内存地址att
。在此地址读取4个字节的内存(因为我们有0xF4
)并将其解释为有符号整数。对于上述情况,这应该显示int
指向的对象的att
成员的正确值。
现在,假设您在p
函数内部,您有一个堆栈分配的do_something
实例。如果您现在尝试获取CClass
的值,则调试器将获取对象本身的地址(基本上为q.att
)并再次添加相应的偏移量4.因为&q
已分配给堆栈,q
处的内存片段是堆栈帧内的位置,其中存储了对象&q + 4
的成员att
的值。到目前为止一切都很好。
接下来,考虑表达式q
,它不是正确类型化的C ++,但调试器似乎只是以通常的方式进行。它采用r.att
(r
)的地址,而不是&r
指向的地址,并再次将r
(att
)的偏移量添加到其中,在从此位置阅读4
之前。由于int
的地址位于堆栈中,因此生成的位置r
不是&r + 4
所指向的对象成员所在的位置,而是您内部的无关位置堆栈帧(如内部其他局部变量或函数参数)。
在您的情况下,r
也会发生同样的情况。由于this
指针是非this
成员函数的不可见第一个参数,因此它也位于函数的堆栈框架中。调试器现在似乎采用static
指针位于堆栈帧中的地址,添加相应的偏移量并输出在那里找到的this
字节的值。实际值是什么,取决于堆栈帧的布局(可能类似于返回地址),但它显然不在4
指向的对象内。