2016-01-22 144 views
0

我試圖將一個類函數的指針作爲變量發送給另一個類。我試圖將這兩個類分開,以便我可以重用代碼而不必在將來進行編輯。將指針指向類函數以指向函數

我編寫在Windows 7上,使用Visual Studio 2015年

DATASTRUCT dataItem = {0, 1, 0, 1, dataText, parentClass::doSomething}; 

childClass.addItem(dataItem); //childClass is initiated as a member of parentClass 

在別處:

typedef struct dataStruct{ 
    double min_x; 
    double max_x; 
    double min_y; 
    double max_y; 
    GLTEXT label; //custom struct for text information 
    void(*function)(void); 
}DATASTRUCT; 

我想childClass能夠去了解其業務,並檢查了某些參數,當childClass完成時,我希望它從parentClass調用doSomething,但實際上並不知道它是嵌套類。

編譯過程中我得到的錯誤是:

無效(父類:: )()不能用於初始化的無效()實體()。

我能夠定義一個標準函數並調用它,但這並不是每個parentClass都唯一的,然後我必須指定我所指的是哪個parentClass :: doSomething。

我發現最簡單的辦法是重新定義指針childClass運作爲void(父類:: *)(),這正是我想要的,但不是如何我想它。

有了這個說法,我不知道在哪裏拿這個,有沒有另一種方式?相似的東西?

編輯:

如果可能的話,我將如何明確送我childClass正確解讀動態函數指針所需要的信息。

所以......「父類::」提前

childClass.addItem(classInformation, dataItem, &parentClass::doSomething); 

或者不接收端總是有知道的嗎?那麼現在是使用void指針的好時機嗎?

我是追着我自己的尾巴還是這是去某個地方?

編輯:

這樣的事情看起來很危險,但在這裏。

childClass.addItem(classInformation, dataItem, static_cast<void*>(&parentClass::doSomething)); 

childClass::callParent(classInformation, void*function){ 
    static_cast<classInformation.something*>(function)(); 
} 

什麼是「classInformation.something」在這種情況下?

+0

成員功能需要一個對象,他們將操作。你如何指定你想要訪問哪一個? –

+0

順便說一句,你真的應該使用'&parentClass :: doSomething'。只有MSVC會原諒你錯過'&',那只是因爲他們試圖與VC++ 6進行bug兼容。 – MSalters

+0

@MSalters我會記住這一點,我曾經在c中添加&之前的函數指針,但是我開始在C++中出現類似指針的奇怪錯誤。到目前爲止,我注意到Visual Studio似乎更喜歡沒有。 – Jarred

回答

0

函數指針實際上是有限的。我建議改用std::function<void()>。請注意,您仍然需要知道哪個對象成員函數可以運行。你可以使用std::bind或lambda來做到這一點:

DATASTRUCT dataItem = 
    {0, 1, 0, 1, dataText, std::bind(&parentClass::doSomething, std::ref(someParentClassObject))}; 
//or 
DATASTRUCT dataItem = 
    {0, 1, 0, 1, dataText, [&someParentClassObject](){ someParentClassObject.doSomething(); }}; 
+0

從來沒有聽說過它,看起來很混亂,但我終於有時間在電腦前試用它,它使用std :: function/bind沒有任何問題。更不用說,這對函數調用沒有任何影響,保留了我想要的格式。你是一個野獸。去有一個美妙的一天。 – Jarred

0

問題是,類成員函數需要知道類變量是哪裏,它不知道它是否必須繼續是一個指向類函數的函數指針,而不引用它是成員之一。所以一個parentClass :: *隱式地有一個指向該對象的指針,而一個函數指針則不會。

基本上,您需要跟蹤對象才能調用其某個成員函數。您可以使用指向對象的指針並從中調用成員函數,也可以使用parentClass :: *,它在後臺執行幾乎相同的操作。

也許有一個更基本的潛在問題,可以讓你解決這個限制。例如,與其問你是否可以這樣做,也許有一種不同的方式可以完成你試圖用它做的任何事情。

+0

如果您使用指向函數的類指針指向函數,爲什麼parentClass需要知道變量的位置?這不就是函數本身意識到在一組內存位置開始的東西嗎? – Jarred

+0

成員函數本身位於內存位置,但它不知道編譯器傳遞指針時它是哪個類的哪個實例。成員函數被編譯和鏈接,然後它的一個副本位於內存中的某個位置。每次創建新對象時,程序都不會創建該代碼的新副本 - 這意味着將爲該類的所有實例調用相同的代碼,因此代碼不知道哪個實例正在調用它,除非它獲得傳遞了一個指針。編譯器隱式傳遞指針。但是一個簡單的函數指針不會。 – Tom

+0

好的,這樣解釋的話對我來說更有意義。我想這個問題應該是如何傳遞一個指向類函數的指針,明確指定哪個類實例沒有明確指定類類型..?我現在只是困惑自己。 – Jarred