C++ this 指针,函数调用中的隐藏参数
Posted
技术标签:
【中文标题】C++ this 指针,函数调用中的隐藏参数【英文标题】:C++ this pointer, hidden argument in function calls 【发布时间】:2013-03-10 12:34:44 【问题描述】:我有一个包含成员的堆栈类和一个名为 push 的函数。
class STACK
int data;
public:
void push(int x)
data=x;
C++ 做了什么来转换这个语句:
s1.push(3);
到
s1.push(this,3);
基本上我的问题是,在生成 this
指针并将其作为隐藏参数传递时会发生什么?
我实际上是在用 C 编写代码。我的目标是拥有一个尽可能接近 OOP 的程序。为此,我将函数指针作为结构的成员。因此,我想知道是否有可能以某种方式跟踪调用函数的结构(如“this”指针)。我不想做类似的事情: s1.push(&s1,3);因为它超出了我的目的。
是否可以转换 s1.push(3);到 s1.push(&1,3);通过宏替换
【问题讨论】:
【参考方案1】:首先要做的事!声明:
s1.push(3);
未翻译为:
s1.push(this, 3);
但是对于这样的事情:
STACK::push(&s1, 3);
其中STACK::push
可以被视为类/命名空间STACK
下的全局/命名空间或静态函数,其原型为:
push(STACK const* pThis, int arg);
this
指针始终是方法(函数)的第一个参数。如果方法的参数为零,它仍然有一个参数(类的this
指针)。
【讨论】:
是否可以通过编码来实现? (我的意思是显式转换为 push(STACK const* pThis, int arg); ) 显而易见的问题是为什么。你为什么要这样做?也许你可以编写一个全局或静态函数并传递类的指针。 我实际上是在用 C 编码。我的目标是拥有一个尽可能接近 OOP 的程序。为此,我将函数指针作为结构的成员。因此,我想知道是否有可能以某种方式跟踪调用函数的结构(如“this”指针)。我不想做类似的事情: s1.push(&s1,3);因为它超出了我的目的。 好吧,你倒霉了。 C 没有很好的面向对象编程的设施。您需要显式传递您的函数应该处理的对象的地址。 是否可以转换 s1.push(3);到 s1.push(&1,3);通过宏替换【参考方案2】:没有魔法
s1.push(3);
只是语法
STACK::push(&s1, 3);
【讨论】:
嗯,这里的“魔力”是push(...)
变成了一个普通的(即 C 类型)函数,带有一个额外的 STACK*
参数。为了避免名称与其他普通函数发生冲突,在内部名称被“修改”以包括类名以及其他内容。
...当方法变为虚拟时,事情会变得有点复杂;)
问题是关于 this 的魔力,这并没有什么魔力,它只是使用的对象的地址。我确实知道让 STACK::push 做正确的事情的magic。
是否可以转换 s1.push(3);到 s1.push(&1,3);通过宏替换
我不确定我理解你所说的宏替换是什么意思,但在有限的意义上你可以做一些类似的事情。见C with Pseudo-Classes。【参考方案3】:
this = &s1
s1的地址是已知的,所以可以传递给STACK::push。就这么简单:)
【讨论】:
我完全同意。但代码行是 s1.push(3);怎么变成s1.push(this,3); 伙计,编译器不是 hello world 程序。 “但代码行是 s1.push(3)”不是一个论点。编译器完成的任务比传递隐藏参数要困难得多。 @DarshanShah:就像代码int main()
在你的文件系统中变成一个可执行文件一样:因为那是编译器所做的。【参考方案4】:
C++ 不能完全转换语句(因为 C++ 是一种语言规范,您可以通过多种方式实现该语言,即使是 - 不道德地 - 有一群奴隶在纸上工作;您不需要计算机,即使你想要一个,拥有 C++)。编译器(例如 GCC)将语句转换为其他一些较低级别的表示。使用 GCC,它是 Gimple 语句,并且可以检查 Gimple 表示,例如带有MELT's probe 或-fdump-tree-gimple 和其他选项(如-fdump-tree-all
或-fdump-tree-ssa
等...)
【讨论】:
【参考方案5】:不幸的是,您必须在 C 中显式或隐式指定指针。
对于 C++,编译器负责将隐式 this
指针设置为类成员函数的参数。在你的代码中,成员函数在编译时被编译器自动修改为void STACK::push(STACK*, int)
,然后,当调用成员函数STACK::push
时,编译器会将对象地址(this
)设置为参数(一般是第一个)到成员函数STACK::push
。
没有C编译器会提供上述功能,因此,设置指针是用户的责任。
【讨论】:
【参考方案6】:在您编辑之后,问题又涉及另一个问题 - C 语言中的 OOP。这很困难且类型不安全,但可以实现。你可以看看 GObject 库,它在 C 中提供了对象系统。我猜它大量使用了宏。
【讨论】:
以上是关于C++ this 指针,函数调用中的隐藏参数的主要内容,如果未能解决你的问题,请参考以下文章