2009-01-27 31 views
6

我試圖將一個指向另一個類中定義的函數的指針傳遞給另一個類。經過大量研究,我相信我的語法是正確的,但我仍然遇到編譯器錯誤。下面是一些代碼,演示了我的問題:無法將指針傳遞到類之間的函數

class Base 
{ 
public: 
    BaseClass(); 
    virtual ~BaseClass(); 
}; 

class Derived : public Base 
{ 
public: 
    // assign strFunction to the function pointer passed in 
    Derived(string (*funPtr)(int)) : strFunction(funPtr); 
    ~Derived(); 

private: 
    // pointer to the function that is passed in 
    string (*strFunction)(int value); 
}; 

class MainClass 
{ 
public: 
    MainClass() 
    { 
     // allocate a new Derived class and pass it a pointer to myFunction 
     Base* myClass = new Derived(&MainClass::myFunction);  
    } 

    string myFunction(int value) 
    { 
     // return a string 
    } 
}; 

當我嘗試編譯這段代碼,我得到的錯誤是

error: no matching function for call to 'Derived::Derived(string (MainClass::*)(int))'

其次

note: candidates are: Derived::Derived(string (*)(int))

任何想法,我可能做錯了嗎?

回答

8

您的語法對於C風格函數指針是正確的。它改成這樣:

Derived(string (MainClass::*funPtr)(int)) : strFunction(funPtr) {} 

string (MainClass::*strFunction)(int value); 

記得打電話strFunction,您將需要一個MainClass對象的實例。我經常發現使用typedefs很有用。

typedef string (MainClass::*func_t)(int); 
func_t strFunction; 

Derived(func_t funPtr) : strFunction(funPtr) {} 
+0

以及如果這些類是分離的並且您不能指定'MainClass :: * funPtr'? – fduff 2012-08-13 11:57:32

+0

然後我會推薦使用一個通用庫,例如​​將參數設置爲`boost :: function `並將函數傳遞給`boost :: bind` – 2012-08-13 12:46:15

0

對象方法有一個隱藏的「this」參數。如果你將該方法傳遞給另一個類,那麼填充「this」參數的是什麼?你可以用靜態(Class)方法來完成它。

2

函數指針(即指向未綁定函數的指針)和指向方法的指針(指向綁定到類定義的非靜態函數的指針)在c++中有所不同。這是因爲非靜態方法有一個隱含的this參數,它要求它們總是在其類的實例的上下文中調用。

你試圖傳遞一個方法指針到一個構造函數,該函數需要一個函數指針。哪個不行。

+0

這很有道理。 – Chris 2009-01-28 19:06:16

4

是的,&MainClass::myFunction的類型是指向成員類型的指針,而string(*)(int)是指向函數的類型。它們不兼容,因爲您必須使用引用或指向類實例的指針,並使用。*或 - > *運算符來使用指向成員的指針,而指向函數的指針不會附加到類,並且可以直接調用。

4

您試圖將指針傳遞到類MainClass的成員函數,但該函數需要一個指向一個普通的,即非成員函數。一個好的總結是here

區別很重要,因爲成員函數有一個隱藏的額外參數告訴功能哪個「this」指針來應用函數。所以指針類型是不可互換的。

0

由於編譯器警告指出,成員函數指針與常規函數指針完全不同。

2

另一個語法問題:


    // assign strFunction to the function pointer passed in 
    Derived(string (*funPtr)(int)) : strFunction(funPtr); 

替換爲:


    // assign strFunction to the function pointer passed in 
    Derived(string (*funPtr)(int)) : strFunction(funPtr) {}; 
1

你可能要考慮使用std::tr1::bindstd::tr1::function類似這樣的(未經測試)代碼:

class Derived: public Base 
{ 
    public: 
    typedef std::tr1::function<string(int)> StringFunc; 

    Derived(StringFunc); 

    ... 

    private: 
    StringFunc strFunction; 
} 

並在MainClass構造函數中:

myBase = new Derived(std::tr1::bind(&MainClass::myFunction, *this, _1); 

bind函數基本上把成員函數綁定到一個特定的對象。它負責編譯器插入的這個指針。