2012-08-25 82 views
0

在我介紹這篇文章底部的代碼之前,我想討論一下我不想要的問題和解決方案。好吧,基本上我從頭開始創建了一個GUI,並且我希望這個允許組件具有自己的點擊執行,所以如果我單擊按鈕或選項卡等等。它會調用Component-> Execute();那麼通常你會做類似於ID的switch語句,如果該組件ID等於n數,那麼它將執行此操作。那對我來說似乎有點愚蠢,我認爲必須有更好的方式。我最終試圖在JAVA中加入一個功能,你會像Component.AddActionListener(new ActionListener(public void execute(ActionEvent ae){}));或類似的東西,我認爲這個功能必須在C++中可能。我最終發現將void函數存儲到一個變量中,隨時可以執行該變量並進行修改。然而,我沒有注意到一個問題,這是隻適用於靜態功能。所以下面你會看到我的問題。我已經通過使用指向SomeClass的指針修補了問題,但是這意味着要爲每個類類型調用單獨的函數,是否沒有辦法將函數回調存儲到非靜態類成員,而不執行下面的策略?而是做一個像註釋掉的代碼一樣的策略?函數調用與類成員?

//Main.cpp

#include <iostream> //system requires this. 
#include "SomeClass.h" 

void DoSomething1(void) 
{ 
    std::cout << "We Called Static DoSomething1\n"; 
} 

void DoSomething2(void) 
{ 
    std::cout << "We Called Static DoSomething2\n"; 
} 

int main() 
{ 
    void (*function_call2)(SomeClass*); 
    void (*function_call)() = DoSomething1; //This works No Problems! 
    function_call(); //Will Call the DoSomething1(void); 
    function_call = DoSomething2; //This works No Problems! 
    function_call(); //Will Call the DoSomething2(void); 

    SomeClass *some = new SomeClass(); //Create a SomeClass pointer; 
    function_call = SomeClass::DoSomething3; //Static SomeClass::DoSomething3(); 
    function_call(); //Will Call the SomeClass::DoSomething3(void); 
    //function_call = some->DoSomething4; //Non-Static SomeClass::DoSomething4 gives an error. 
    //function_call(); //Not used because of error above. 
    function_call2 = SomeClass::DoSomething5; //Store the SomeClass::DoSomething(SomeClass* some); 
    function_call2(some); //Call out SomeClass::DoSomething5 which calls on SomeClass::DoSomething4's non static member. 
    system("pause"); 
    return 0; 
} 

//SomeClass.hpp

#pragma once 

#include <iostream> 

class SomeClass 
{ 
    public: 
     SomeClass(); 
     ~SomeClass(); 

    public: 
     static void DoSomething3(void); 
     void DoSomething4(void); 
     static void DoSomething5(SomeClass* some); 
}; 

//SomeClass.cpp

#include "SomeClass.h" 

SomeClass::SomeClass(void) 
{ 

} 

SomeClass::~SomeClass(void) 
{ 

} 

void SomeClass::DoSomething3(void) 
{ 
    std::cout << "We Called Static DoSomething3\n"; 
} 

void SomeClass::DoSomething4(void) 
{ 
    std::cout << "We Called Non-Static DoSomething4\n"; 
} 

void SomeClass::DoSomething5(SomeClass *some) 
{ 
    some->DoSomething4(); 
} 

什麼,我會做不是二次修復我想要的確切答案,但現在滿足了我的需求,並允許額外的功能,如果沒有這些功能會變得過於複雜 存在。

//Component.hpp

#pragma once 

#include <iostream> 
#include <windows.h> 
#include <d3dx9.h> 
#include <d3d9.h> 

#include "Constants.hpp" 
#include "ScreenState.hpp" 
#include "ComponentType.hpp" 

using namespace std; 

class Component 
{ 

    static void EMPTY(void) { } 
    static void EMPTY(int i) { } 

    public: 
    Component(void) 
    { 
     callback = EMPTY; 
     callback2 = EMPTY; 
     callback_id = -1; 
    } 

    Component* SetFunction(void (*callback)()) 
    { 
     this->callback = callback; 
     return this; 
    } 

    Component* SetFunction(void (*callback2)(int), int id) 
    { 
     this->callback_id = id; 
     this->callback2 = callback2; 
     return this; 
    } 

    void execute(void) 
    { 
     callback(); 
     callback2(callback_id); 
    } 

} 
+0

如果您添加C++標籤,您將獲得更多幫助 – mathematician1975

回答

1

的用於指針到成員函數的語法如下:

struct Foo 
{ 
    void bar(int, int); 
    void zip(int, int); 
}; 

Foo x; 

void (Foo::*p)(int, int) = &Foo::bar; // pointer 

(x.*p)(1, 2);       // invocation 

p = &Foo::zip; 

(x.*p)(3, 4);       // invocation 

心在函數調用,這是需要額外的括號獲得正確的運算符優先級。成員解引用運算符爲.*(並且還有一個來自實例指針的->*)。

+0

我認爲這是正確的方式來處理SomeClass.DoSomething4的內容嗎? 這個問題我已經讓我嘗試澄清一點,但以下是:我喜歡它是我可以存儲任何類型的函數到一個變量這種方式我可以調用像「執行(無效) ;」它會執行該函數指針。這將是非常類似於如何在按鈕,標籤等工作的行動事件。有沒有可能將上面的代碼轉換成模板類,所以我不會強迫使用Foo,而是可以使用任何東西?有點像在Java中的對象 –

+0

編輯:這看起來有點有用,我會試圖修改它有點爲我的用法,也許我會在新的評論出現之前想出一些東西。 –

+0

@ user1625157:類的類型是函數指針類型的一部分。你不能有一個通用的''Anything「:: *(int,int)'類型... –