2012-01-05 97 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