我需要将此代码转换为Visual Studio 2008的函数指针调用。GetValue()
func可以是虚拟的,但并非总是如此,并且不同上下文中的GetObject()
将返回不同的类型。 / p>
...
res = GetObject()->GetValue(x, y);
...
调用函数将传递GetObject()->GetValue
(指向func的指针+应该调用该函数的对象实例),参数将由被调用函数提供:
void Foo( (int T::func*)(int, int) )
{
...
res = func(x, y);
...
}
void Bar()
{
Foo( & GetObject()->GetValue );
}
谢谢!
答案 0 :(得分:5)
你真的希望std::tr1::function<int(int int)>
完成这份工作。检查它在MSDN上的文档,你应该是一个快乐的人。
答案 1 :(得分:0)
您的Foo
还需要指向类T
的对象:
typedef int (T::MyMemFun*)(int, int);
void Foo(MyMemFun f, T * t)
{
...
res = t->*f(x, y);
...
}
答案 2 :(得分:0)
如果GetObject()
可以返回不同的类型,那么您将需要使用模板。像这样:
template <class T>
int Foo(const T &o) {
return o->GetValue(x, y);
}
int Bar() {
return Foo(GetObject());
}
这基本上是编译时多态
修改强>: 如果您还需要指定要调用的函数,那么您可以执行以下操作:
template <class T, int (T::*F)(int,int)>
int Foo(const T &o) {
return (o->*F)(x, y);
}
int Bar() {
// there is probably some template magic you can do to avoid knowing "Type" here..
return Foo<Type, &Type::GetValue>(GetObject());
}
修改强>: 这可以归结为,你可以写这样的代码:
#include <iostream>
struct A {
int GetValue(int x, int y) {
return 42;
}
};
struct B {
int GetValue(int x, int y) {
return 123;
}
};
template <class T, int (T::*F)(int,int)>
int Foo(T &o) {
return (o.*F)(0, 1);
}
int main() {
A a;
B b;
std::cout << Foo<A, &A::GetValue>(a) << std::endl;
std::cout << Foo<B, &B::GetValue>(b) << std::endl;
}
类型A
和B
不相关,但我可以将公共处理程序传递给它们。问题是,为什么这有必要?为什么不做这样的事情(避免整个混乱):
#include <iostream>
struct A {
int GetValue(int x, int y) {
return 42;
}
};
struct B {
int GetValue(int x, int y) {
return 123;
}
};
int Foo(int x) {
return x
}
int main() {
A a;
B b;
std::cout << Foo(a.GetValue()) << std::endl;
std::cout << Foo(b.GetValue()) << std::endl;
}
我没有看到你可以通过模型确定调用所有类型,对象和函数来获得什么,也可以直接进行,或者使用一些简单的薄包装器。
另外,为什么不只是让GetObject
返回的所有类型都使用它们继承的公共接口,所以你可以按照预期使用虚函数?这有一点“代码味道”......
答案 3 :(得分:0)
您的函数是全局的,因此您的对象可能是全局的,具有包装函数:
public class MyMsgObject
{
void ShowMsg(char[] Msg);
// other methods
};
// ...
// this function belongs to a class, is a method
void MyMsgObject::ShowMsg(char[] Msg)
{
cout << "Method: " << Msg <<"\n";
}
// this method doesn't belong to any class,
// its global
void GlobalShowMsg(char[] Msg)
{
cout << "Global: " << Msg <<"\n";
}
// global var obj, before method wrapper:
MyMsgObject myGlobalObject;
void MethodWrapperShowMsg(char[] Msg)
{
// method pointer is global,
// your objects must be used as globals:
myGlobalObject.ShowMsg(Msg);
}
// declare function pointer ("functor"),
// syntax is weird
typedef
void (*MyGlobalFunctorType) (char[] Msg);
void main()
{
// declare function pointer variable
MyGlobalFunctorType MyGlobalFunctorVar = null;
// test function pointer variable with global function
MyGlobalFunctorVar = &GlobalShowMsg;
MyGlobalFunctorVar("Hello Earth");
// instantiate class into an object variable
myGlobalObject = new MyMsgObject();
// test function pointer variable with wrapper function
MyGlobalFunctorVar = &MethodWrapperShowMsg;
MyGlobalFunctorVar("Hello Moon");
} // void main(...)
干杯。