5

我想存儲一個指向一個對象的指針和一個指向它的已知簽名方法的指針。如果我知道這個類,那麼這個指針有類型:C++存儲一個指向未知類的成員函數的指針

int (MyClass::*pt2Member)(float, char, char) 

但如何我可以存儲指針,如果我不知道類型?

我想要做這樣的事情:

myObject.callThisFuncLater(&otherObject, &otherObject::method) 

我怎麼能一個指向方法method存儲在myObject後來打電話了嗎?

+1

六十億重複。 – Puppy

+1

@DeadMG:顯示他們:)我的計數器停留在2,178,933個問題總計 – sehe

+0

您稍後調用它時會使用什麼參數? – Beta

回答

2

您可以使用boost::function(和boost::bind)來存儲稍後調用的一段代碼。

class MyClass 
{ 
public: 
    void callThisFuncLater(boost::function< int (float, char, char) > callBack); 
}; 
... 
myObject.callThisFuncLater(boost::bind(&otherObject::method, &otherObject)); 
+1

我可能錯了,但是應該切換'&otherObject'和'&otherObject :: method'嗎? – Vortico

+0

@Vortico你是對的,我很抱歉。我要編輯我的帖子來糾正它。 –

5

做到這一點,如果你有機會獲得TR1 STL庫擴展(海合會和Visual Studio 2008及以後可用最簡單的方法是,性病::功能和std ::綁定可以用來包裝。調用以後可以調用此功能也是提升功能和提升綁定可用:

#include <functional> 

class MyClass { 
public: 
    template<typename T> callThisFuncLater(T& otherObject, 
             int(T::*)(float, char, char) method) { 
    return storedInvocation_ = std::bind(otherObject, 
            method, 
            std::placeholders::_1, // float 
            std::placeholders::_2, // char 
            std::placeholders::_3); // char 
    } 

    int callStoredInvocation(float a, char b, char c) { 
    storedInvocation_(a, b, c); 
    } 

private: 
    std::function<int(float, char, char)> storedInvocation_; 
}; 
-1

個人而言,我會選擇不同的設計很簡單,因爲使用C的成員函數指針不容易共事我個人。會選擇使用接口並從這些接口繼承,並沿着這些接口解析。

成員函數指針的問題之一是它們在不同的編譯器上以不同的方式實現。如果您使用Borland/Embarcardero編譯器並想限制自己,可以使用關鍵字__closure,但很可能您不是,因此您必須使用其他特定於編譯器的實現,或者使用其中一種boost輔助類如函數。

但是,如果您遇到了在C++中使用成員函數指針很有幫助的情況,請重新考慮您的設計。

+0

閉包的標準替代方法是lambda函數,但這仍然不是成員函數的實際替代。 – MSalters

3

沒有簡單這樣做的方式,如最初內置於語言或標準庫(儘管它最近已添加)。如果您熟悉Boost,他們將包含一個解決方案 - Boost.Function

如果由於某種原因,但是,你不能或不願使用Boost,有這樣使用模板(其中,不可否認,是相當類似升壓轉換器的解決方案)的通用方法:

class FncPtr 
{ 
public: 
    virtual int call(float, char, char) = 0; 
}; 

template <typename T> 
class ClassFncPtr : public FncPtr 
{ 
    int (T::*pt2Member)(float, char, char); 
    T *inst; 
public: 
    ClassFncPtr(T* who, int (T::*memfunc)(float,char,char)) 
     : inst(who), pt2Member(memfunc) 
    { 
    } 
    int call(float a, char b, char c) 
    { 
     return (inst->*pt2Member)(a,b,c); 
    } 
}; 

template <typename T> 
FncPtr * makeFuncPointer(T* who, int (T::*memfunc)(float,char,char)) 
{ 
    return new ClassFncPtr<T>(who,memfunc); 
} 

如果您願意,您還可以繼承FncPtr以便能夠使用非類功能。