“this”指针存储在内存中的确切位置?它是在堆栈上、堆中还是数据段中分配的?
#include <iostream>
using namespace std;
class ClassA
{
int a, b;
public:
void add()
{
a = 10;
b = 20;
cout << a << b << endl;
}
};
int main()
{
ClassA obj;
obj.add();
return 0;
}在上面的代码中,我调用了成员函数add(),接收器对象被隐式地作为'this‘指针传递。this在内存中存储在哪里?
发布于 2013-05-16 23:54:44
其他答案很好地解释了典型的编译器如何实现this (通过将其作为隐式的第一个参数传递给函数)。
我认为看看C++ ISO规范明确说明了这一点也很有用。根据C++03 ISO规范,§9.3.2/1:
在非静态(9.3)成员函数体中,关键字
this是一个非左值表达式,其值是为其调用函数的对象的地址。
需要注意的是,this is 不是一个变量-它是一个表达式,就像表达式1 + 2 * 3是一个表达式一样。这个表达式的值被允许存储在几乎任何地方。编译器可能会将它放到堆栈中,并将其作为隐式参数传递给函数,或者它可能会将它放在寄存器中,并且可以想象它会将它放入堆或数据段中。在这里,C++规范有意地为实现提供了一些灵活性。
我认为“语言律师”的答案是“这是完全由实现定义的,而且从技术上讲,this不是一个指针,而是一个计算结果为指针的表达式。”
希望这能有所帮助!
发布于 2013-05-16 18:56:57
最简单的方法是将this看作是一个始终自动传递的隐藏的额外参数。
因此,一个虚构的方法如下:
size_t String::length(void) const
{
return strlen(m_string);
}实际上更像是这样的:
size_t String__length(const String *this)
{
return strlen(this->m_string);
}和一个类似这样的调用:
{
String example("hello");
cout << example.length();
}变得类似于:
cout << String__length(&example);请注意,上面的转换被简化了,希望能让我的观点更清晰一点。不需要在注释中填上“哇,方法重载的编组在哪里?”-type反对。:)
这就将问题转化为“参数存储在哪里?”,答案当然是“视情况而定”。:)
它通常在堆栈上,但也可以在寄存器中,或者编译器认为对目标体系结构有利的任何其他机制中。
发布于 2013-05-16 18:59:58
this通常作为方法的隐藏参数传递(不同调用约定中唯一的区别是如何传递)。
如果你打电话给:
myClass.Method(1, 2, 3);编译器生成以下代码:
Method(&myClass, 1, 2, 3);其中第一个参数实际上是指向this的指针。
让我们检查一下以下代码:
class MyClass
{
private:
int a;
public:
void __stdcall Method(int i)
{
a = i;
}
};
int main(int argc, char *argv[])
{
MyClass myClass;
myClass.Method(5);
return 0;
}通过使用__stdcall,我强制编译器通过堆栈传递所有参数。如果您随后启动调试器并检查汇编代码,您将发现类似以下内容:
myClass.Method(5);
00AA31BE push 5
00AA31C0 lea eax,[myClass]
00AA31C3 push eax
00AA31C4 call MyClass::Method (0AA1447h) 如您所见,该方法的参数通过堆栈传递,然后将myClass的地址加载到eax寄存器并再次推送到堆栈上。换句话说,this被视为此方法的常规参数。
https://stackoverflow.com/questions/16585562
复制相似问题