作者kwpn (ITSST)
看板C_and_CPP
標題Re: [問題] 將 class B 之 mem. func 塞到 class A 之 func.ptr
時間Sat Jul 18 10:29:36 2015
http://codepad.org/J87uWOk5 // 20150718 1300 edited
這是比較舊也比較傳統的做法,
許多C語言的API常使用這種方式讓C++物件被callback。
(ex: CreateThread, ffmpeg的AVCodecContext有個member叫opaque)
這樣做可以避免class Display知道有PlaneDlg這class,
也就是說,傳入的class不限定於PlaneDlg。
但比起原po最早的寫法,這寫法就不能用在global function,
所以若不是有特殊限制,我比較建議是用C++11的std::function,
因為可接受任何同型的callable object,
(ex: global function, member function, lambda, std::function,
return of std::bind, ...)
//----------------------------------------------------
20150718 edited
抱歉,上面的說法有誤,這做法global function也能用,
但class Display呼叫的函式要改成
void MyFunc(int iSel)
{
if(m_CallBackFunc)
if(rand() & 1) //assume
m_CallBackFunc(m_CallBackObj, iSel);
}
而建立Display物件時只傳入global function, 物件就傳NULL進入即可。
※ 引述《notBeing (read and be read)》之銘言:
: ※ 引述《EdisonX (卡卡獸)》之銘言:
: : 開發平台(Platform): (Ex: VC++, GCC, Linux, ...)
: : vs2010
: : 問題(Question):
: : 我想在自己的 class Display 實現 callback 功能 , 讓其他 class 使用
: : 目前我想比較正式的方法應該是用 template 方式去做,但這份
: : class 要改成 template 的話有些工程,故想加上 function pointer 方式去做,
: : 但發現好像不能塞其他 class 之 member function,
: : 問題之程式碼簡化如下,
: : 同步附 Code http://codepad.org/nT3XDA5q
: class Display
: {
: private:
: void ( PlaneDlg::*m_CallBackFunc )(int);
: PlaneDlg *m_P;
: public:
: Display( void ( PlaneDlg::*CallBackFunc )(int), PlaneDlg *P )
: : m_P( P ), m_CallBackFunc( CallBackFunc )
: {
: }
: void ToUpdateDisplay( int iSel )
: {
: if( m_CallBackFunc && m_P )
: if( rand() & 1 )
: ( m_P->*m_CallBackFunc && m_P )( iSel );
: }
: class PlaneDlg
: {
: private:
: Display m_display;
: public:
: PlaneDlg():
: m_display( this, &::UpdateDisplay )
: {
: }
: void UpdateDisplay( int iGrp )
: {
: //....
: }
: }
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 219.85.193.165
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1437186579.A.E5F.html
※ 編輯: kwpn (219.85.193.165), 07/18/2015 10:32:19
※ 編輯: kwpn (219.85.193.165), 07/18/2015 10:50:50
推 LiloHuang: 如果 Compiler 不支援 C++11 可用 boost::function 07/18 10:58
※ 編輯: kwpn (219.85.193.165), 07/18/2015 10:59:34
※ 編輯: kwpn (219.85.193.165), 07/18/2015 12:25:05
推 EdisonX: 謝謝您的細心回覆 , 這方法看起來的確很像 Win32 設計 07/18 12:34
→ kwpn: 我名稱取錯了,取成CallBackObj,但一般都是取名為user_data 07/18 13:00
※ 編輯: kwpn (219.85.193.165), 07/18/2015 13:04:07