【发布时间】:2013-10-09 10:26:12
【问题描述】:
下面通过指向成员函数调用D::foo函数的方法会产生错误:必须使用.*或->*在'f(...)中调用指向成员函数'
.. 当然,这不是我们调用指向成员函数的方式。
正确的调用方式是(d.*f)(5); OR (p->*f)(5);
我的问题是,'有没有办法在没有左侧类对象的情况下调用类的成员函数?我想知道我们是否可以将类对象 (this) 作为常规参数传递?
在我看来,归根结底(在汇编/二进制级别)类的所有成员函数都是正常函数,它们应该对 n + 1 个参数进行操作,其中(+1 代表this)
如果我们在下面讨论D::foo 函数,在汇编/二进制级别它应该对两个参数进行操作:
- 类对象本身(指向名为
this的D类对象的指针) - 和
int。
那么,有没有办法(或破解)调用 D::foo 并将类对象作为函数参数传递给它,而不是在类对象上使用 . or -> or .* or ->* 运算符?
示例代码:
#include <iostream>
using namespace std;
class D {
public:
void foo ( int a ) {
cout << "D" << endl;
}
int data;
};
//typedef void __cdecl ( D::* Func)(int);
typedef void ( D::* Func)(int);
int main ( void )
{
D d;
Func f = &D::foo;
f(&d, 5);
return 1;
}
一种方法是使用增强绑定,即
(boost:: bind (&D::foo, &d, 5)) ();
编辑: "请注意,我不是在寻找这个程序的有效版本,我知道如何让它工作"
【问题讨论】:
-
看这个question的答案
-
没有“魔法”。在
bind结果类型的operator()中的某处将类似于(ptr->*fun)(arg);您只是看不到它,因为它隐藏在库实现中。 -
这不是“人为限制”,就像在声明后要求
;是“人为限制”一样。这只是语言的语法。 -
" 归根结底,它是一个函数,它接受两个参数,第一个是对 D 类对象本身的引用(this),第二个是'int'。 ——不,不是。归根结底,它是一个接受参数值和
this值的函数,不一定按此顺序。非静态成员函数很可能使用与非成员函数不同的调用约定。因此,它不一定与以this作为第一个参数调用常规函数相同,因为this可能会在与通常传递第一个参数的位置不同的寄存器或堆栈槽中传递。 -
@Mike Seymour:Bind 不会进行调用,它只是让它提升函数对象。任何带有签名 arg0> D& 和 arg1> int 的函数都可以调用它。这就是我所说的魔法。