我想給類事件函數,如.onShow()和.onHide(),所以當對象顯示時,.onShow()函數將運行。我怎樣才能讓功能如此變化:設置一個類實例的功能,它已經定義
MyClass myInst = MyClass();
myInst.onShow = OnShowFunction;
是否有可能允許這樣做?
我想給類事件函數,如.onShow()和.onHide(),所以當對象顯示時,.onShow()函數將運行。我怎樣才能讓功能如此變化:設置一個類實例的功能,它已經定義
MyClass myInst = MyClass();
myInst.onShow = OnShowFunction;
是否有可能允許這樣做?
這是你如何做到這一點(和打動/在同一時間嚇壞你的牛orkers):
#include <iostream>
class MyClass
{
public:
void (MyClass::*OnShow)() ;
void OnShowFunction() ;
} ;
int main (int argc, char** argv)
{
MyClass C ;
C.OnShow = MyClass::OnShowFunction ;
(C.*C.OnShow)() ;
}
void MyClass::OnShowFunction()
{
std::cout << "void MyClass::OnShowFunction()\n" ;
}
是的,這是可能的。
您需要使用函數指針或封裝函數指針和其他可調用對象的封裝器,如function
,它可以在C++ 0x,C++ TR1和Boost中以各種形式找到。
根據您使用回調的方式,像Boost.Signals這樣的信號庫可能更優雅。
您可以使用函數指針或std::function
(也在BOOST中)來實現此目的。然而,看起來你可能正試圖在C++中採用JavaScript或腳本語言編程風格 - 我會警告你,你應該改變你的編程風格,取決於它如何適應語言。 C++中的一個典型替代方法是使onShow
爲可由衍生工具覆蓋的虛擬方法。
您可能不希望在運行時動態更改函數,如果您確實需要,其他答案之一會告訴您如何使用函子。但對我來說,這聽起來像你想讓不同的對象根據對象的某些屬性具有不同的功能。
這是虛函數是:
你定義在基類的動作。然後在派生類中,根據對象的行爲方式給出實際的實現。
class MyClass
{
public:
virtual void onShow() = 0;
};
class Window: public MyClass
{
public:
virtual void onShow() { /* Draw Window */ }
};
void aboutToShowObject(MyClass& obj)
{
obj.onShow();
}
+1並注意當馬丁說,你不會在運行時這樣改變功能,它不意味着你沒有選擇你想在運行時創建哪個對象。您仍然可以根據上下文創建一個派生類或另一個派生類。 Functor或者類似std :: function的包裝只有在對象的生命週期中想要更改函數時纔有用。 – log0 2010-09-05 20:47:26
您可以使用std :: function這是一個包裝類,它可以讓您以安全的方式指定函數和C函數。
但是,使用函子層次結構是一個非常簡單的解決方案。
class Object
{
BaseOnShow& onShow;
}
class onShow1 : BaseOnShow { ... };
class onShow2 : BaseOnShow { ... };
...
Object obj;
onShow1 OnShowFunction; // careful about the lifetime of this one
obj.onShow = OnShowFunction;
然後,像往常一樣,必須通過虛函數成員使用onShow的特定功能。
請注意,與Martin的回答相比,onShow的生命週期不同於obj的生命週期。 – log0 2010-09-05 21:10:27
如果要動態地改變在運行時函數指針,你可以保持函數指針成爲會員,並使用)調用該函數指針稱爲OnShow中(默認的方法:
#include <iostream>
using namespace std;
void OnShow() {
cout << "Showing!" << endl;
}
typedef void(*EventProc)();
class Widget {
private:
EventProc m_ep;
public:
Widget() : m_ep(0) {}
void SetOnShow(EventProc ep) {m_ep = ep;}
void OnShow() {(*m_ep)();}
};
int main() {
Widget w;
w.SetOnShow(::OnShow);
w.OnShow();
return 0;
}
謝謝TonyK,我得到了這個工作完全我只是做了一些改變:void OnShowFunction(){/ *做的東西* /} class MyClass { public: void(* OnShow)(); }; int main(int argc,char ** argv) { MyClass C; C.OnShow = OnShowFunction; (* OnShow)(); } – 2010-09-05 21:55:00