..当然这不是我们如何调用指向成员的函数.
正确的呼叫方式是(d.* f)(5); OR(p-> * f)(5);
我的问题是,’有没有办法调用一个类的成员函数没有类对象在左边?我想知道我们是否可以传递类对象(this)作为常规参数?
在我看来,在一天结束时(在汇编/二进制级别),类的所有成员函数都是正常的函数,它们应该在n 1个参数上运行,其中(1是为此)
如果我们在下面讨论D :: foo函数,那么在程序集/二进制级别,它应该运行在两个参数上:
>类对象本身(指向D类对象的指针称为此)
>和int.
所以,有没有一种方式(或hack)调用D :: foo,类对象传递给它作为函数参数而不是使用.或 – >或.*或 – > *类对象上的运算符?
示例代码:
#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绑定,即
(boost:: bind (&D::foo,&d,5)) ();
编辑:
“请注意,我不是在寻找这个程序的一个版本,它的作品,我知道如何使它的工作”
解决方法
Evil.h:
#ifdef __cplusplus extern "C" { #endif struct MyStruct { #ifdef __cplusplus MyStruct(); void method(int); #endif }; #ifdef __cplusplus } #endif
Evil.cc:
#include <iostream> #include "evil.h" MyStruct::MyStruct() { std::cout << "This is MyStruct's constructor" << std::endl; } void MyStruct::method(int i) { std::cout << "You passed " << i << std::endl; }
Evil.c:
#include "evil.h" int main() { struct MyStruct my_struct; _ZN8MyStructC1Ev(&my_struct); /* MyStruct::MyStruct() */ _ZN8MyStruct6methodEi(&my_struct,3); /* MyStruct::method(int) */ return 0; }
这恰好适用于我在Linux上的gcc和g的组合,但是不用说它依赖于平台ABI,并且在调用下划线大写字母的函数时违反了C89标准.它几乎肯定不会与虚拟功能一起工作,我不倾向于尝试.这也可能是我写过的最邪恶的事情.但还是…
编辑:引用OP:
In my mind,at end of the day (at assembly/binary level) all member functions of a class are normal functions which should operate on n + 1 arguments where (+1 is for
this
)
虽然CFront的每个编译器都是这样做的,但这只是一个实现细节. C标准是不能指定如何实现成员函数,它们应该如何运行.
因为它是一个实现细节,不同的平台以不同的方式进行.这不仅仅是名字的扭曲.例如,在Linux上使用的调用约定指定将其作为第一个参数传递;其他实现(Borland,IIRC?)将其作为最后一个参数.
所以,如果要将成员函数作为普通函数来处理,那么您必须将自己限制在特定的ABI上.这篇文章提供了一个例子,说明你如何做到这一点(或者说,为什么你真的不应该这样做)
so,is there a way (or hack) to call D::foo with class object passed to it as function argument instead of using . or -> or .* or ->* operators on class object?
一个平台特定的,恶心的肮脏的黑客…