2012-01-05 62 views
2

我有一些图书馆这样的功能:C++无效*到参数的函数

class myConsole 
{ 
    void addCommand(std::string command, void* fn); 
    ... 
} 

,并在我的课我有这样的功能:

void myApp::TestFn(const std::vector<std::string> & args) 
{ 
    // do something 
} 
在同一个班我把这个

void myApp::initApp() 
{ 
    myConsole::getSingleton().addCommand("FirstTest", &myApp::TestFn); 
} 

,但是这给了我这个错误:

error c2664 cannot convert parameter 2 from 'void(__thiscall myApp::*)(const std::vector<_Ty>&)' to 'void *'

我该如何解决这个问题?

在此先感谢!

+0

你以后打算如何使用'void * fn'? – 2012-01-05 14:19:33

+0

'myApp :: TestFn'访问'myApp'的任何成员变量吗? – hmjd 2012-01-05 14:19:52

+0

我需要做这样的事情:http://www.ogre3d.org/tikiwiki/ConsoleCode&structure=Cookbook – ghiboz 2012-01-05 14:23:24

回答

9

You can't解决这个问题。你不能可靠地将一个函数指针转换为void *并返回。

(我建议你重新设计程序,并留下清晰的void*;还有它没有真正的需要在C++中。)

1

这里的问题是,你试图通过一个类的方法,因为它是一个void *指针。这是无法完成的。

这样做的正确方法是使用void addCommand (std::string, void *)方法的模板。喜欢的东西

class myConsole { 
    template <typename T> 
    void addCommand(std::string command, T f); 
}; 

struct Callback { 
    myApp &app; 
    Callback (myApp &a) : app(a) { 
    } 
    void operator() (const std::vector<std::string> &args) { 
     app.TestFn(args); 
    } 
}; 

void myApp::initApp() 
{ 
    myConsole::getSingleton().addCommand("FirstTest", Callback(*this)); 
} 

这使您在C++回调的原则,但我认为你需要的东西比这个解决方案更加灵活,因为你真的想选择自动将由回调(要执行在这种情况下,命令TestFn)。

1

您应该避免void*,特别是在尝试使用函数指针时。我将假设您只查看myApp类中的成员函数指针,并且您只对以const std::vector<std::string> &args作为参数的成员函数指针感兴趣。此类型定义将创建适当的类型,并调用它MemFunType

typedef void (myApp :: * MemFunType) (const std::vector<std::string> &); 

这是一个完整的例子(ideone),其中有两个你可能感兴趣的,TestFnTestFnBackwards不同的成员函数。这个例子可能不是很有用,但它提供了一些成员函数指针的例子。

#include<iostream> 
#include<vector> 
using namespace std; 

struct myApp; 

struct myConsole 
{ 
     typedef void (myApp :: * MemFunType) (const std::vector<std::string> &); 
      void addCommand(std::string command, MemFunType fn); 
}; 

struct myApp { 
     void TestFn(const std::vector<std::string> & args) { 
       cout << " TestFn" << endl; 
       for(std :: vector<std::string> :: const_iterator i = args.begin(); i!=args.end(); i++) { 
         cout << *i << endl; 
       } 
     } 
     void TestFnBackwards(const std::vector<std::string> & args) { 
       cout << " TestFnBackwards" << endl; 
       for(std :: vector<std::string> :: const_reverse_iterator i = args.rbegin(); i!=args.rend(); i++) { 
         cout << *i << endl; 
       } 
     } 
     static myApp & getSingleton(); 
} ma; 
myApp& myApp :: getSingleton() { 
     return ma; 
} 

void myConsole :: addCommand(std::string , MemFunType fn) { 
     vector<string> words; 
     words.push_back("hello"); 
     words.push_back("world"); 
     myApp &ma = myApp :: getSingleton(); 
     (ma.*fn)(words); // execute the member on the singleton object, using the words as the argument. 
} 

int main() { 
     myConsole m; 
     m.addCommand("FirstTest", &myApp::TestFn); 
     m.addCommand("FirstTest", &myApp::TestFnBackwards); 
} 
+0

谢谢,但在这种情况下,我需要链接在控制台类的myApp类的参考(如果我有多个类,调用myConsole是很难...) – ghiboz 2012-01-05 16:14:38

+0

@ghiboz,我认为你需要编辑你的问题显着。我建议你停止编写代码,并尝试清楚地表达你的目标是在这里。是否真的需要'addCommand'(用简单的英文)接受三条信息:(1)指向myApp的*实例*的引用/指针,(2)成员函数的名称调用myApp对象,(3)命令字符串? – 2012-01-05 18:57:29