青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Creative Commons License
本Blog采用 知識(shí)共享署名-非商業(yè)性使用-禁止演繹 3.0 Unported許可協(xié)議 進(jìn)行許可。 —— Fox <游戲人生>

游戲人生

游戲人生 != ( 人生 == 游戲 )
站點(diǎn)遷移至:http://www.yulefox.com。請(qǐng)訂閱本博的朋友將RSS修改為http://feeds.feedburner.com/yulefox
posts - 62, comments - 508, trackbacks - 0, articles - 7

項(xiàng)目中使用了消息通信機(jī)制,因?yàn)橄㈩愋头浅6?,相?yīng)的,處理消息的地方代碼也非常多。

自然而然想到MFC中的消息映射:

創(chuàng)建一個(gè)缺省MFC框架程序的解決方案Test,在Test.h中看到以下內(nèi)容:

class Ctest_mfcApp : public CWinApp
{
public:
    Ctest_mfcApp();

// 重寫
public:
    virtual BOOL InitInstance();

// 實(shí)現(xiàn)
    afx_msg void OnAppAbout();
    DECLARE_MESSAGE_MAP()
};

 

其中,最緊要的就是DECLARE_MESSAGE_MAP()這個(gè)宏,相關(guān)內(nèi)容展開如下:

struct AFX_MSGMAP_ENTRY
{
    UINT nMessage;   // windows message
    UINT nCode;      // control code or WM_NOTIFY code
    UINT nID;        // control ID (or 0 for windows messages)
    UINT nLastID;    // used for entries specifying a range of control id's
    UINT_PTR nSig;   // signature type (action) or pointer to message #
    AFX_PMSG pfn;    // routine to call (or special value)
};

struct AFX_MSGMAP
{
    const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
    const AFX_MSGMAP_ENTRY* lpEntries;
};

#define DECLARE_MESSAGE_MAP() \
protected: \
    static const AFX_MSGMAP* PASCAL GetThisMessageMap(); \
    virtual const AFX_MSGMAP* GetMessageMap() const; \

其中AFX_PMSG不再解析下去,我們認(rèn)為這是一個(gè)指向特定消息對(duì)應(yīng)的實(shí)現(xiàn)函數(shù)的函數(shù)指針,這幾個(gè)宏的作用可簡單理解成為Test這個(gè)項(xiàng)目定義了一個(gè)靜態(tài)的消息映射表。當(dāng)消息到來時(shí),從消息隊(duì)列中彈出消息并分發(fā)到具有入口實(shí)現(xiàn)的上層CWnd派生窗口。用戶只需要注冊(cè)消息,實(shí)現(xiàn)消息入口函數(shù)就夠了,這在MFC中一般放在.cpp文件頭部。Test.cpp中頭部有以下內(nèi)容:

BEGIN_MESSAGE_MAP(CTest, CWinApp)
    ON_COMMAND(ID_APP_ABOUT, &CTest::OnAppAbout)
    // 基于文件的標(biāo)準(zhǔn)文檔命令
    ON_COMMAND(ID_FILE_NEW, &CWinApp::OnFileNew)
    ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen)
    // 標(biāo)準(zhǔn)打印設(shè)置命令
    ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()

這里是為消息枚舉值與消息實(shí)現(xiàn)函數(shù)建立映射,其中涉及到的宏的展開如下:

#define ON_COMMAND(id, memberFxn) \
    { WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSigCmd_v, \
        static_cast<AFX_PMSG> (memberFxn) },

#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
    PTM_WARNING_DISABLE \
    const AFX_MSGMAP* theClass::GetMessageMap() const \
        { return GetThisMessageMap(); } \
    const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap() \
    { \
        typedef theClass ThisClass;                           \
        typedef baseClass TheBaseClass;                       \
        static const AFX_MSGMAP_ENTRY _messageEntries[] =  \
        {

#define END_MESSAGE_MAP() \
        {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } \
    }; \
        static const AFX_MSGMAP messageMap = \
        { &TheBaseClass::GetThisMessageMap, &_messageEntries[0] }; \
        return &messageMap; \
    }                                  \
    PTM_WARNING_RESTORE

按照上述思路得到的相似代碼如下:

// Test.h
typedef void (* funCall)(void*);        // 消息執(zhí)行函數(shù)類型

struct tagMsgEntry                      // 消息入口結(jié)構(gòu)
{
    int            nMsgType;            // 消息類型
    funCall        MsgRun;              // 消息執(zhí)行函數(shù)
};

struct tagMsgMap                        // 消息映射表結(jié)構(gòu)
{
    const tagMsgMap* (__stdcall* funGetBaseMsgMap)();
    const tagMsgEntry* pMsgEntries;     // 消息入口集
};

class CMessage
{
    // ...
protected:
    static const tagMsgMap* __stdcall GetThisMsgMap();
    virtual const tagMsgMap* GetMsgMap() const;
};

// Test.cpp
const tagMsgMap* CMessage::GetMsgMap() const
{
    return GetThisMsgMap();
}

const tagMsgMap* __stdcall CMessage::GetThisMsgMap()
{
    static const tagMsgEntry MsgEntries[] =
    {
        { MSG_SOME_ONE, SomeOneFunc },
        { MSG_SOME_TWO, SomeTwoFunc },
        { MSG_NULL, NULL }
    };
    static const tagMsgMap msgMap =
    {
        &CBaseMessage::GetThisMsgMap,    // 父類消息映射表
        &MsgEntries[0]
    };
    return &msgMap;
}

int CMessage::MsgProc(int nMsgType)
{
    switch( nMsgType )
    {
    case MSG_SOME_ONE:
        {

        }
        break;
    }
    return CBaseMessage::MsgProc(nMsgType);
}

這種處理的優(yōu)點(diǎn)在于,子類沒有定義的消息實(shí)現(xiàn)接口,可以使用父類接口實(shí)現(xiàn)。不過在現(xiàn)在的消息處理中,我們一般不需要由基類來完成,因此可以不依賴基類接口,使用宏可以使代碼看上去更加簡潔。

___________________________________________________________

簡化版本的消息映射采用以下方式,簡單清晰:

// Test.h
#define REG_MSG_FUNC(nMsgType, MsgFunc) \
    CMessge::RegisterCallFunc(nMsgType, MsgFunc); \

typedef void (* function)(void*);

typedef std::map<int, function> MSG_MAP;
typedef MSG_MAP::const_iterator MSG_CITR;

class CMessage
{
    // ...
public:
    static const MSG_MAP& GetMsgMap();
    static void RegisterCallFunc(int nMsgType, void(* Func)(void *))
    {
        s_MsgMap[nMsgType] = Func;
    }

    int CMessage::Run(int nMsgType)                // 消息公用執(zhí)行函數(shù)
    {
        MSG_ITR itr = s_MsgMap.find(nMsgType);
        if( s_MsgMap.end() != itr )
        {
            itr->second(this);
        }
    }

protected:
    static MSG_MAP            s_MsgMap;            // 消息映射表
};

// UserTest.cpp -- 用戶在使用時(shí)對(duì)自己關(guān)心的消息予以注冊(cè), 入口函數(shù)予以實(shí)現(xiàn)即可
REG_MSG_FUNC(MSG_SOME_ONE, SomeOneFunc)

void SomeOneFunc(CBaseMessage *pMsg)
{
    return;
}

___________________________________________________________

最近忙的焦頭爛額,正好寫到消息,稍微整理一下,提供些許借鑒。

Feedback

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)[未登錄]  回復(fù)  更多評(píng)論   

2008-09-30 12:32 by cppexplore
頂一下
前幾天我也剛寫了一個(gè),用在線程消息的處理中,我的消息類型做數(shù)組下標(biāo)了,直接定位取處理函數(shù),這都是無關(guān)緊要的細(xì)節(jié)。關(guān)鍵在ON_COMMAND宏的展現(xiàn)方式,我的處理線程消息,名字起做ON_MESSAGE
整體思路基本都是一樣的,呵呵。

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2008-10-10 08:50 by Condor
對(duì)于成員函數(shù)這個(gè)寫法應(yīng)該沒用了。

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2008-10-10 10:23 by Fox
@Condor
你說的這個(gè)問題我也考慮了,既然被提到,可以查看新一篇:http://www.shnenglu.com/Fox/archive/2008/10/10/63625.html

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-18 02:30 by OwnWaterloo
@cppexplore
【消息類型做數(shù)組下標(biāo)了,直接定位取處理函數(shù),這都是無關(guān)緊要的細(xì)節(jié)。】
這恰恰是最重要的細(xì)節(jié) …… 這樣做得不償失……



# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-18 02:35 by OwnWaterloo
@cppexplore
我再說明白一點(diǎn):
既然【用消息類型做數(shù)組下標(biāo),直接定位處理函數(shù)】,為什么不直接使用虛函數(shù)?

你的方案是為了消息路由而消息路由,沒能理解采用消息路由的”苦衷“——如果采用更容易理解的虛函數(shù)來實(shí)現(xiàn),虛表將占用比較多的資源,不得已而采用消息路由。

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)[未登錄]  回復(fù)  更多評(píng)論   

2009-02-18 12:00 by cppexplore
@OwnWaterloo
歡迎來我blog討論:http://www.shnenglu.com/CppExplore 這篇http://www.shnenglu.com/CppExplore/archive/2008/11/07/66216.html下。查表是本質(zhì),為什么要使用虛函數(shù)?更容易理解?MFC的消息映射展現(xiàn)方式很難理解嗎? 虛函數(shù)更容易擴(kuò)展嗎? 說到虛函數(shù)占用較多資源而導(dǎo)致不得已采用消息路由,我不能認(rèn)同,這個(gè)因素在整個(gè)系統(tǒng)中的開銷你有沒有量化過?比如 因?yàn)椴捎盟鼘?dǎo)致并發(fā)數(shù)下降了多少多少之類?歡迎來我blog討論。

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-18 16:29 by OwnWaterloo
@cppexplore

1. 時(shí)間消耗

時(shí)間消耗自然不用說,是你的實(shí)現(xiàn)最得意的部分,o(1)。
同樣,虛函數(shù)也是o(1)。

2. 空間消耗

假設(shè)你總共有N個(gè)消息,你仔細(xì)看看你的實(shí)現(xiàn):
是不是每個(gè)(要處理消息的)類有一個(gè)長度會(huì)N的函數(shù)表,
空間大小至少是N×sizeof(void*);
每個(gè)對(duì)象有一個(gè)指向(或間接指向)該表的指針,
空間大小至少是sizeof(void*)。

虛函數(shù)的經(jīng)典實(shí)現(xiàn)的空間消耗也是one class one vtbl, one object one vptr,和你的實(shí)現(xiàn)還是相同的。


這就回答了你一個(gè)問題:
【我不能認(rèn)同,這個(gè)因素在整個(gè)系統(tǒng)中的開銷你有沒有量化過?比如 因?yàn)椴捎盟鼘?dǎo)致并發(fā)數(shù)下降了多少多少之類?】
兩者的時(shí)間空間效率是完全一致的,即使我沒有量化過,也可以肯定,不會(huì)導(dǎo)致并發(fā)數(shù)下降。



# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-18 16:40 by OwnWaterloo
@cppexplore

【查表是本質(zhì)】
這句你說到重點(diǎn)了,虛函數(shù)和你實(shí)現(xiàn)的那個(gè)還有哪些所謂的用C實(shí)現(xiàn)OO的,都是查表。

【為什么要使用虛函數(shù)?更容易理解?MFC的消息映射展現(xiàn)方式很難理解嗎? 虛函數(shù)更容易擴(kuò)展嗎?】
你這個(gè)實(shí)現(xiàn)就是在『模擬』虛函數(shù)。

上面的時(shí)空分析,可以量化,我有把握你會(huì)同意我的觀點(diǎn)——兩者時(shí)空效率完全一樣——這個(gè)擴(kuò)展性嘛,不容易量化 ……

你可以試著把你的實(shí)現(xiàn)用虛函數(shù)改寫一下(再次說明,時(shí)空效率完全一樣)??纯词欠裼X得虛函數(shù)更容易理解,更容易擴(kuò)展。



btw:推薦你看看這個(gè),MFC會(huì)什么會(huì)采用消息映射而不是虛函數(shù)的理由,《C++多態(tài)技術(shù)的實(shí)現(xiàn)和反思》
http://dev.yesky.com/189/2385189.shtml

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-18 18:03 by OwnWaterloo
@cppexplore

再看了下你的實(shí)現(xiàn),好像我們討論的著重點(diǎn)不一樣。

1. 你的系統(tǒng)里,是不是首先有這樣一個(gè)需求:
因?yàn)槟撤N原因(分布式,進(jìn)程間,無鎖線程),消息的發(fā)送者不能直接調(diào)用消息處理函數(shù),而是傳送一個(gè)消息代碼來表示需要處理的類型?

消息代碼即是win32中的WM_XX或者你的系統(tǒng)中的 enum MsgType { MSG_TYPE_1=65, ...  };



2. 消息的處理者,又需要按照約定(即消息代碼的含義),將其映射到某個(gè)處理函數(shù)中。

如 win32 中
switch (message) {
case WM_XXX:
   return OnXXX(hwnd,message,wparam,lparam);
...
}

或者你的系統(tǒng)中的
switch(msg->type)
{
    
case MSG_TYPE_1:
         do_msg_type_1_();
         
break;
    
case MSG_TYPE_2:
         do_msg_type_2_();
         
break;
    ..
    
default:
             do_default_msg_();
             
break;
}



在這一步,確實(shí)是你的實(shí)現(xiàn)方式時(shí)間效率比較高。
但是在win32中, 這樣做不太現(xiàn)實(shí) ……  1000多個(gè)消息,表格就要包含1000多項(xiàng),而且大多都是DefWndProc。

并且,在這一步中,虛函數(shù)根本就提供不了任何幫助
你的著重點(diǎn)在這一步?


3. 你想實(shí)現(xiàn)一個(gè)消息處理者B,它對(duì)大多數(shù)消息的處理方式同A一樣,這時(shí)候如何盡可能的使用A的實(shí)現(xiàn)?
(暫不說依賴于某實(shí)現(xiàn)是不太恰當(dāng)?shù)脑O(shè)計(jì),在MFC中多如牛毛……)

我的著重點(diǎn)在這里,我對(duì)處理這步的觀點(diǎn)是: 『消息類型做數(shù)組下標(biāo)了,直接定位取處理函數(shù)』與『覆寫虛函數(shù)』相比,時(shí)空效率是相同的,我覺得后者更容易理解和擴(kuò)展。


# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)[未登錄]  回復(fù)  更多評(píng)論   

2009-02-18 18:21 by cppexplore
@OwnWaterloo
怎么不直接去我blog回復(fù)呢 呵呵
其實(shí) 時(shí)間消耗 之類并不是我最得意的東西,這種實(shí)現(xiàn)的細(xì)節(jié) 我并不太關(guān)注,所以質(zhì)疑你以前說的 “虛函數(shù)占用較多資源而導(dǎo)致不得已采用消息路由”,如何實(shí)現(xiàn)并不重要,關(guān)鍵的是容易理解,容易擴(kuò)展,容易維護(hù),容易移植,容易簡單化。
win32 你是指win32 的界面設(shè)計(jì)? 業(yè)務(wù)系統(tǒng)里 基本不同的消息有不同的實(shí)現(xiàn),我的本意其實(shí)都不在實(shí)現(xiàn),而在于簡單的思想,因此是查表實(shí)現(xiàn) 還是虛函數(shù)實(shí)現(xiàn) 也都無所謂,只要最后有統(tǒng)一的擴(kuò)展方式。

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)[未登錄]  回復(fù)  更多評(píng)論   

2009-02-18 18:55 by cppexplore
@OwnWaterloo
呵呵,最后的問題歸結(jié)為:哪種更容易理解和擴(kuò)展。
超大工程當(dāng)然是數(shù)組方式之上用宏展現(xiàn)最容易理解和擴(kuò)展了,簡潔直接。幾十w行的代碼,用虛函數(shù),文件數(shù)量的迅速膨脹 找個(gè)東西都找不到在哪里,所有東西交織錯(cuò)亂在一起,最終維護(hù)程序的人都會(huì)想:要是有張表就好了,只看表就知道那個(gè)函數(shù)處理哪個(gè)消息,而宏的展現(xiàn)就是如此。 當(dāng)然如果用宏包裹下虛函數(shù)的實(shí)現(xiàn),結(jié)果就一樣了。
并且數(shù)組表只是一個(gè)思路,不攜帶任何面向?qū)ο蟮恼Z義,在這個(gè)業(yè)務(wù)系統(tǒng)里可用,在那個(gè)業(yè)務(wù)系統(tǒng)里也可用,虛函數(shù)有這么好的移植性嗎?有這么簡單化嗎?

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-19 01:57 by OwnWaterloo
@cppexplore
【怎么不直接去我blog回復(fù)呢 呵呵】
好像是cppblog對(duì)url的分析有點(diǎn)問題,這個(gè)url: http://www.shnenglu.com/CppExplore/archive/2008/11/07/66216.html
會(huì)被截取,只將前面一部分(也就是你的主頁)制作成鏈接,點(diǎn)過去沒看見什么文章……
后來才發(fā)現(xiàn)這個(gè)問題,找到那篇文章……
【容易理解,容易擴(kuò)展,容易維護(hù),容易移植,容易簡單化】
嗯,這是重點(diǎn)。同時(shí)我也贊同你文章里最后一句話【一句話:重要的是思想,不是平臺(tái)和語言?!?br> 
"你的實(shí)現(xiàn)就是模擬C++虛函數(shù)的經(jīng)典實(shí)現(xiàn)",這個(gè)觀點(diǎn)你贊同嗎?
你的系統(tǒng)需要考慮向C(以及不支持虛函數(shù)的語言)移植嗎?
 
如果贊同且不需要,那么繼續(xù)討論理解、擴(kuò)展、維護(hù)、簡單。
你的系統(tǒng)具體要做什么不太了解,我用win32作例子可以嗎?比如,現(xiàn)在需要關(guān)心的消息只有2個(gè):
enum MsgType {
    WM__LBUTTONDOWN 
/*= 0*/,
    WM__SIZING,
    
// 
};
struct Msg {
    MsgType type;
    HWND    hwnd;
    WPARAM  wparam;
    LPARAM  lparam;
};

如果使用C++虛函數(shù)機(jī)制:
 
class IHandler {
public:
    
virtual ~IHandler() {};
protected:
    
virtual void OnLButtonDown(POINTS pt,bool ctrl,bool shift,bool l,bool m,bool r) = 0 {};
    
virtual void OnSizing(RECT& rc,int side) = 0 {};
public:
    LRESULT Do(Msg
* msg) {
        
switch (msg->type) {
            
case WM__LBUTTONDOWN:
                OnLButtonDown(MAKEPOINTS(msg
->lparam)
                             ,msg
->wparam & MK_CONTROL
                             ,msg
->wparam & MK_SHIFT
                             ,msg
->wparam & MK_LBUTTON
                             ,msg
->wparam & MK_MBUTTON
                             ,msg
->wparam & MK_RBUTTON);
                
return 0;
            
case WM__SIZING:
                OnSizing(
*reinterpret_cast<RECT*>(msg->lparam),msg->wparam);
                
return 0;
        }

        
return DefWindowProc(msg->hwnd,msg->type,msg->wparam,msg->lparam);
    }

}
;
 
具體的消息處理類可以這樣:
class Handler1 : public IHandler {
    
void OnLButtonDown(POINTS pt,bool ctrl,bool shift,bool l,bool m,bool r) {
        IHandler::OnLButtonDown(pt,ctrl,shift,l,m,r);
    }

    
void OnSizing(RECT& rc,int side) {
        IHandler::OnSizing(rc,side);
    }

}
;
 
上面的基類的虛函數(shù)帶有默認(rèn)實(shí)現(xiàn),但設(shè)置為純虛函數(shù)。
具體類必須實(shí)現(xiàn)每個(gè)消息處理過程,如果不關(guān)心,可以簡單使用基類實(shí)現(xiàn)。
另一種方式:基類提供默認(rèn)實(shí)現(xiàn),并且不是純虛函數(shù);具體類只需覆寫關(guān)心的消息。
 
另一方面,上面的基類沒有使用表格,如果覺得switch case 不好維護(hù),也可以使用表格。
 
兩方面都采用另一種方案的話,基類就如下:
class IHandler {
public:
    
virtual ~IHandler() {};
private:
    
virtual void OnLButtonDown(POINTS pt,bool ctrl,bool shift,bool l,bool m,bool r)  {};
    
virtual void OnSizing(RECT& rc,int side)  {};
public:
    LRESULT Do(Msg
* msg) {
        assert(msg
->type>=0 && msg->type<WM__SIZING);
        
return MsgProcs[msg->type](msg->hwnd,msg->type,msg->wparam,msg->lparam,this);
    }


private:
    typedef LRESULT (
*MsgProc)(HWND,MsgType,WPARAM,LPARAM,IHandler* handler);
    
const static MsgProc MsgProcs[];
    
static LRESULT OnLButtonDown(HWND,MsgType,WPARAM wparam,LPARAM lparam,IHandler* handler) {
        handler
->OnLButtonDown(MAKEPOINTS(lparam)
                              ,wparam 
& MK_CONTROL
                              ,wparam 
& MK_SHIFT
                              ,wparam 
& MK_LBUTTON
                              ,wparam 
& MK_MBUTTON
                              ,wparam 
& MK_RBUTTON);
        
return 0;
    }

    
static LRESULT OnSizing(HWND,MsgType,WPARAM wparam,LPARAM lparam,IHandler* handler) {
        handler
->OnSizing(*reinterpret_cast<RECT*>(lparam),wparam);
        
return 0;
    }

}
;

const IHandler::MsgProc IHandler::MsgProcs[] = {
    IHandler::OnLButtonDown,
    IHandler::OnSizing,
}
;

具體類的編寫就更簡單: 假設(shè)僅關(guān)心OnLButtonDown
class Handler1 : public IHandler {
    
void OnLButtonDown(POINTS pt,bool ctrl,bool shift,bool l,bool m,bool r) {
        printf(
"(%d,%d) ctrl=%d,shitf=%d\n",pt.x,pt.y,ctrl,shift);
    }

}
;

 

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-19 02:16 by OwnWaterloo
                              考慮擴(kuò)展
 
添加一個(gè)新的消息處理類。
如果基類不是純虛函數(shù),那最簡單了,覆寫需要關(guān)心的消息就可以了。
如果是純虛函數(shù),需要實(shí)現(xiàn)所有消息處理函數(shù),對(duì)不關(guān)心的消息,使用基類默認(rèn)處理。
 
而你的方案,不得不將所有的消息都映射一遍——因?yàn)椤鞠㈩愋妥鰯?shù)組下標(biāo),直接定位取處理函數(shù)】——即使不關(guān)心而作一個(gè)空函數(shù)。 
BEGIN_MESSAGE_MAP(SessionManager,SessionMsg)
    ON_MESSAGE(MSG_TYPE_1, SessionManager::do_msg_type_1_)
    ON_MESSAGE(MSG_TYPE_2, SessionManager::do_msg_type_2_)
    
// .. MORE
END_MESSAGE_MAP()
如果不是這樣,請(qǐng)務(wù)必告訴我你是怎么不使用虛函數(shù)實(shí)現(xiàn)的。
 
 
添加一個(gè)新的消息種類(消息代碼)
如果可以保證消息代碼連續(xù),可以使用上面的方案2,在表格中多加入一條。
如果不能保證消息代碼連續(xù)(并且非常稀疏),就只能采用swtich case。
 
已經(jīng)編寫好的具體的消息處理類,如果都可以安全忽略該消息,那么可以采用上面的方案2——基類有默認(rèn)實(shí)現(xiàn)且不純虛——那么除了基類,已經(jīng)編寫好的具體類都不需要修改。
如果不全都可以安全忽略該消息,那么可以采用上面的方案1——基類有空實(shí)現(xiàn),但是純虛——具類中可以忽略該消息的,使用基類實(shí)現(xiàn),不能忽略的,編寫處理函數(shù)。
 
而你的方案,一旦添加一個(gè)新的消息處理代碼(同時(shí)要保證連續(xù)),所有的消息處理類都必須在其表格中增加一項(xiàng)。

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-19 02:16 by OwnWaterloo
移植性確實(shí)會(huì)在不支持虛函數(shù)的語言中完敗。
論理解、擴(kuò)展、維護(hù)、簡單的話,你現(xiàn)在仍然覺得虛函數(shù)比不上表格嗎?

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)[未登錄]  回復(fù)  更多評(píng)論   

2009-02-19 10:16 by cppexplore
@OwnWaterloo
呵呵 你覺得你的想法來源于面向?qū)ο蟮募埳险劚]有貶義)以及基于win32的mfc框架程序設(shè)計(jì)。
我的實(shí)現(xiàn)不是為了模擬虛函數(shù)的實(shí)現(xiàn),只是為了實(shí)現(xiàn)一個(gè)易維護(hù)的消息映射而已。
首先 對(duì)象A不能直接向?qū)ο驜直接發(fā)送消息,需要調(diào)用對(duì)象B的ON_send_msg,由B自己的方法向自己發(fā)送消息,由B的DO_Msg方法處理消息,當(dāng)然發(fā)送動(dòng)作和處理動(dòng)作在不同的線程內(nèi)。任何對(duì)象向B發(fā)送消息都要調(diào)用B自己的方法。也就是說對(duì)象B的具體消息類型對(duì)其它對(duì)象是不可見的。
因此對(duì)象B中的消息類型是連續(xù)的,并且不存在自己不感興趣的消息,既然不感興趣,就不會(huì)存在這個(gè)消息類型,只要是存在的就是感興趣的,就是要處理的。也不存在對(duì)多個(gè)消息,處理方式相同的問題,既然處理方式相同,它們就是同一個(gè)消息。
其次 你還是回避了大型程序開發(fā)中,使用虛函數(shù)方式,文件個(gè)數(shù)膨脹的問題。
最后 我討論的是線程間的消息傳遞和映射,你的有偏向于 已經(jīng)發(fā)送到UI線程的消息,對(duì)責(zé)任鏈模式上的 各個(gè)對(duì)象的后續(xù)處理。

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-19 22:42 by OwnWaterloo
@cppexplore

第1個(gè)疑問:
系統(tǒng)中所有類使用的消息代碼是否是同一套?都是
enum MsgType
{
MSG_TYPE_1=65,//64一下預(yù)留,用于統(tǒng)一的管理控制
MSG_TYPE_2,
..
MSG_TYPE_MAX
};
???

第2個(gè)疑問:(同時(shí)也是回答)
確實(shí)如你所說,我是【紙上談兵】。
我沒有【大型程序】的開發(fā)經(jīng)驗(yàn),更是不能理解:
【大型程序開發(fā)中,使用虛函數(shù)方式,文件個(gè)數(shù)膨脹的問題?!?br>這是為什么? 請(qǐng)指教~~~ 昨天就想問你了,字打多了就忘了……

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)[未登錄]  回復(fù)  更多評(píng)論   

2009-02-19 22:51 by cppexplore
@OwnWaterloo
不是同一套,只有64以下的是相同。64以上的各個(gè)線程之間可以重復(fù),因?yàn)閷?duì)其他對(duì)象是不可見得,所以不存在沖突問題。可以定義USER_MSG_START=64.
項(xiàng)目越大,越需要表格,容易維護(hù),容易擴(kuò)展,容易找對(duì)應(yīng)關(guān)系,也就是看一個(gè)文件就知道所有,而不是在幾十個(gè)上百個(gè)文件里查找。當(dāng)然要看你的虛函數(shù)實(shí)現(xiàn)成什么樣子了。
我舉的例子,對(duì)象B是管理類,同時(shí)也是線程類。里面管理了很多的對(duì)象,B拿到消息也是找到對(duì)應(yīng)的對(duì)象去處理,貌似你一直談的是后續(xù)。
而你在MFC里看到的是同一套,那是因?yàn)樗鼈兌荚赨I線程里,同屬于一個(gè)線程,一個(gè)管理類。

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-19 23:23 by OwnWaterloo
@cppexplore
我覺得加QQ聊會(huì)快一點(diǎn)…… “六久久思武柳留靈”

不是同一套,那么A向B發(fā)一個(gè)65以上的消息,B如何知道代表什么含義呢?
要么:A只向B發(fā)64以下的消息。
要么:存在T1,T2, ... Tn個(gè)線程,每個(gè)線程下分別有
A11,A12, ... An1...
A21,A22, ... An2...
...
A[i][j]只會(huì)和A[i][k]直接交互
A[i][j]和A[k][l]通過某種機(jī)制間接交互



-----------------------------
【貌似你一直談的是后續(xù)。 】
可能是這樣的,我在
http://www.shnenglu.com/Fox/archive/2008/09/29/63056.aspx#74178
也說了。

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)[未登錄]  回復(fù)  更多評(píng)論   

2009-02-20 10:19 by cppexplore
@OwnWaterloo
上班不能qq 呵呵 下班加你
A不能以指定消息值的方式向B發(fā)消息,通過調(diào)用B自身的ON_MSG方法發(fā)送。也就是除了B自己,誰也不知道它具體消息的枚舉值。
64一下的也是調(diào)用B自身的方法發(fā)送,不過這些是B基類中的方法。

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2011-10-15 16:04 by
人 需要一種簡單的 東西來支撐屬于自身內(nèi)心的簡單,這樣的簡單一直以來是無形的,就如同所有存在的 對(duì)于支撐簡單的東西已經(jīng) 進(jìn)行過的時(shí)候,那么內(nèi)心當(dāng)中還是缺少對(duì)于無法割舍的簡單的 內(nèi)涵

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2011-10-15 16:06 by
在某一種環(huán)境下面其實(shí)簡單的來說在于一旦沒有了這樣的一種現(xiàn)實(shí),簡單的環(huán)境是否在可能變化的環(huán)境當(dāng)中產(chǎn)生簡單的過程那樣如此簡單明了

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2011-10-15 16:07 by
所以自己的內(nèi)心真誠的東西不是對(duì)于某一種勢(shì)力的那種附和,而是對(duì)于在這個(gè)過程當(dāng)中自身能夠決定進(jìn)入某一種勢(shì)力需要的那種條件的 認(rèn)可

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2011-10-15 16:08 by
在各種各樣的 范圍內(nèi)決定一個(gè)人能夠簡單的進(jìn)行自身的活動(dòng)范圍內(nèi) 并且 能夠達(dá)到一些盡可能需要的行為內(nèi),需要的不僅僅是可靠性的 過程,更重要的是價(jià)值活動(dòng)的產(chǎn)生

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2011-10-15 16:09 by
在過程行為當(dāng)中能夠明確的 在于是已經(jīng)形成出來的新的一種競(jìng)爭(zhēng)力自身需要的一種內(nèi)心活動(dòng) 當(dāng)中產(chǎn)生的角色轉(zhuǎn)換的 過程當(dāng)中需要的互動(dòng)意識(shí)與能力

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2011-10-15 16:10 by
因此各種各樣的簡單絕對(duì)不是取決于自身在竭盡全力自后需要的條件,而是自身竭盡全力的過程當(dāng)中自己需要的休息的素質(zhì)與能力的那種背景考量的能力

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2012-04-16 09:10 by
基本上來說一個(gè)人成熟的機(jī)制恐怕是能夠讓自己能夠在不斷的磨合當(dāng)中逐漸消失成見的過程,就一個(gè)成熟的那種業(yè)績體系來說,實(shí)際上現(xiàn)在的復(fù)雜在于業(yè)績對(duì)象的那種針對(duì)的安全對(duì)象的成熟度沒有,如果僅僅針對(duì)的是一種瘋子般的業(yè)務(wù)來說的業(yè)績或者組織層面來說的業(yè)績,這樣的機(jī)制成熟的業(yè)績體系是不存在的一個(gè)方式。

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2012-04-16 09:13 by
實(shí)際上業(yè)績組合套拳的組合一定夾雜某一種對(duì)于私心認(rèn)可的范疇內(nèi)達(dá)到的應(yīng)急范疇內(nèi)實(shí)現(xiàn)對(duì)于業(yè)績整個(gè)機(jī)制的認(rèn)識(shí),從表面上來看,一旦業(yè)績沒有屬于自己范圍的業(yè)績過程,整個(gè)的業(yè)績鏈被居心叵測(cè)的人所掌握,那么業(yè)績機(jī)制上面的成熟機(jī)制在實(shí)現(xiàn)的過程永遠(yuǎn)被這樣或者那樣的理由所圈繞。一個(gè)成熟的業(yè)績機(jī)體本身上面是由于其中業(yè)績機(jī)體上面有按照其中規(guī)律方式運(yùn)轉(zhuǎn)的模式旋轉(zhuǎn),而與時(shí)代與行業(yè),和管理它的人就更加沒有關(guān)系的了

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2012-04-16 09:16 by
業(yè)績機(jī)制上面的成熟度在于在不斷的磨合的組合的過程當(dāng)中永遠(yuǎn)不可能按照面上面的業(yè)績組合形成業(yè)績機(jī)制過程,業(yè)績機(jī)制表明的是在業(yè)績最初形成的時(shí)候,需要使用各種各樣關(guān)于技巧性的使用,一旦業(yè)績成熟,則不過是一種對(duì)于業(yè)績形成上面需要依照的規(guī)律模式行駛其中業(yè)績機(jī)制形成的規(guī)律線而已。

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2012-04-16 09:19 by
業(yè)績機(jī)制形成的規(guī)律線絕對(duì)不是建立在回復(fù)其它層面的上面的不斷的 解釋層次上面表現(xiàn)出來的那種心安理得局面上面的業(yè)績機(jī)制,業(yè)績機(jī)制的形成在于自己認(rèn)為需要付出多少的代價(jià)愿意承受這樣的一種業(yè)績機(jī)制的形成,業(yè)績機(jī)制的形成一般是競(jìng)爭(zhēng)分析--競(jìng)爭(zhēng)對(duì)手分析---柜臺(tái)分析---賺錢分析---承載風(fēng)險(xiǎn)分析---合理的業(yè)績軌道,這個(gè)業(yè)績機(jī)制的形成在于一旦在那種對(duì)于業(yè)績本身模式不認(rèn)可,而且浮于人事層面上面是永遠(yuǎn)不可能體會(huì) 到這樣的一個(gè)業(yè)績機(jī)制形成的過程的。

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2012-04-16 09:22 by
基于對(duì)于業(yè)績機(jī)制形成的事實(shí),然后規(guī)劃屬于自身現(xiàn)狀的業(yè)績狀況就能夠發(fā)現(xiàn),充分的運(yùn)用屬于自己的認(rèn)識(shí)與人事與實(shí)力來驗(yàn)證對(duì)于業(yè)績機(jī)制的本身帶來的效果,然后再這樣的一種效果當(dāng)中明確這樣的一種業(yè)績機(jī)制承載出來一個(gè)怎么樣的自己的體驗(yàn)當(dāng)中,從而對(duì)于自己有一個(gè)或者有一種全新的認(rèn)識(shí)的過程,至少在這個(gè)過程當(dāng)中,能夠承載屬于自己職業(yè)生命力的安全模式

# re: 消息映射機(jī)制的簡單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2012-04-16 09:25 by
確切的說,業(yè)績機(jī)制承載的職業(yè)生命力具體表現(xiàn)在屬于一種胸襟,沒有一種胸襟,格局的誕生恐怕只能夠越來越小,胸襟不是以職業(yè)生命力的安全作為安全,而恰恰相反,胸襟是站在或者基于職業(yè)生命力維護(hù)的基礎(chǔ)上面去考慮胸襟本身的得失或者愿意承受的東西和不愿意承受的順應(yīng)心靈的一種呼喚。
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美二区在线看| 欧美激情一二三区| 日韩午夜激情av| 美女尤物久久精品| 亚洲国产欧美久久| 欧美国产一区在线| 中文久久精品| 欧美日韩一区二区三区四区在线观看| 亚洲理论在线观看| 一区二区激情| 国产亚洲精久久久久久| 蜜臀a∨国产成人精品| 免费成人小视频| 一本色道久久综合亚洲精品按摩 | 国产欧美在线看| 久久国产精品久久精品国产| 久久精品一二三区| 一本久久综合| 午夜精品久久久久99热蜜桃导演| 国内偷自视频区视频综合| 欧美国产日韩视频| 欧美性视频网站| 久久亚洲综合色| 欧美日韩国产另类不卡| 久久国产直播| 欧美另类综合| 久久女同精品一区二区| 欧美日韩大陆在线| 久久综合给合| 欧美午夜剧场| 欧美黄色一级视频| 国产日韩欧美一区二区| 亚洲美女在线看| 在线成人亚洲| 亚洲欧美韩国| aa日韩免费精品视频一| 久久久精品999| 亚洲小说欧美另类社区| 久久这里只有| 久久精品夜色噜噜亚洲aⅴ| 欧美区一区二区三区| 蜜臀va亚洲va欧美va天堂| 国产精品国产精品国产专区不蜜| 免费亚洲一区二区| 国产精品在线看| 一区二区三区欧美| 一区二区国产日产| 欧美 日韩 国产一区二区在线视频| 午夜精品国产精品大乳美女| 欧美国产日本韩| 久久综合久久综合这里只有精品 | 国产日韩综合一区二区性色av| 亚洲精品日韩久久| 亚洲乱码国产乱码精品精天堂 | 狂野欧美激情性xxxx| 久久国产精品毛片| 国产精品色在线| 亚洲色诱最新| 亚洲欧美日韩国产综合在线| 欧美另类高清视频在线| 亚洲人成啪啪网站| 国产亚洲一区精品| 欧美一区不卡| 久久免费精品日本久久中文字幕| 欧美一级免费视频| 亚洲激情一区二区三区| 在线观看中文字幕不卡| 久久国产精品久久久久久久久久| 欧美在线视频免费观看| 国产欧美日韩一区二区三区在线| 在线亚洲免费| 午夜久久电影网| 国产毛片久久| 欧美自拍偷拍午夜视频| 麻豆亚洲精品| 亚洲激情中文1区| 欧美电影在线| 亚洲老司机av| 亚洲一区二区三区精品视频| 国产精品国产福利国产秒拍| 亚洲欧美日韩在线综合| 久久久久久久波多野高潮日日 | 麻豆国产va免费精品高清在线| 麻豆精品一区二区av白丝在线| 亚洲高清123| 欧美日韩亚洲免费| 午夜精品久久久久久久99水蜜桃 | 午夜亚洲福利| 久久尤物视频| 一区二区三区 在线观看视频| 国产精品xxxav免费视频| 午夜精品剧场| 亚洲第一精品夜夜躁人人爽| 一区二区日韩| 国产自产精品| 欧美精品成人一区二区在线观看 | 女人色偷偷aa久久天堂| 亚洲精品一线二线三线无人区| 亚洲视频每日更新| 国产一区二区高清| 欧美伦理在线观看| 午夜欧美精品久久久久久久| 亚洲国产精品成人综合| 小处雏高清一区二区三区| 亚洲电影免费观看高清完整版在线观看| 欧美高清你懂得| 性做久久久久久免费观看欧美| 欧美成人在线免费视频| 亚洲女性裸体视频| 亚洲国产小视频在线观看| 国产精品一区久久| 欧美精品一区二区三区高清aⅴ| 午夜精品一区二区三区四区| 亚洲人成高清| 欧美sm视频| 久久精品一区二区| 亚洲欧美另类国产| 99视频精品免费观看| 一区二区在线不卡| 国产欧美日韩另类视频免费观看| 欧美刺激性大交免费视频| 久久er99精品| 午夜精品短视频| 中文有码久久| 99国产精品久久| 亚洲欧洲日韩综合二区| 欧美99久久| 久久久久久久久久久一区| 午夜精品在线视频| 欧美大片第1页| 国产香蕉97碰碰久久人人| 欧美日韩国产欧美日美国产精品| 久久午夜电影网| 久久久久国产精品一区| 香蕉免费一区二区三区在线观看 | 欧美国产第一页| 久久深夜福利免费观看| 欧美一区二区免费| 午夜精彩国产免费不卡不顿大片| 一区二区久久久久| 一区二区三区欧美在线| 这里只有精品视频| 在线一区免费观看| 亚洲一区二区av电影| 亚洲一区二区三区免费视频| av成人手机在线| 亚洲一区综合| 午夜视频一区在线观看| 亚洲欧美日韩一区二区三区在线观看 | 国产香蕉97碰碰久久人人| 国产一区视频观看| 国外成人免费视频| 国语自产精品视频在线看8查询8| 国产精品视频久久久| 国产精品日韩欧美一区| 国产日韩欧美一区二区三区在线观看 | 亚洲国产精品va在线看黑人动漫| 女女同性女同一区二区三区91| 久久综合网hezyo| 老司机一区二区| 91久久黄色| 这里只有精品电影| 午夜在线a亚洲v天堂网2018| 欧美在线免费播放| 米奇777在线欧美播放| 欧美成人精品在线视频| 欧美日韩精品在线| 国产精品视频网| 一色屋精品亚洲香蕉网站| 亚洲人体影院| 午夜精品久久久| 欧美1区2区3区| 中文av字幕一区| 久久久久综合| 欧美午夜性色大片在线观看| 国产日韩av在线播放| 91久久久在线| 久久大逼视频| 亚洲精品一区二区三区不| 亚洲欧美日韩在线| 欧美激情1区2区| 国产日韩欧美综合| 一本不卡影院| 美女精品视频一区| 中文一区二区在线观看| 久久中文欧美| 国产精品一区二区久久精品| 亚洲电影第三页| 亚洲欧美国产高清| 欧美成黄导航| 欧美一级视频免费在线观看| 欧美日本高清视频| 在线精品国产成人综合| 午夜视频在线观看一区二区三区| 欧美成年人视频网站欧美| 性视频1819p久久| 国产精品国产a级| 亚洲电影免费| 欧美激情中文不卡| 欧美一区二区三区四区在线|