2012-11-13 33 views
8

我在寫一些消息處理代碼,每個消息都是POD結構。在寫這個的方法是定義一個抽象基類,爲每個消息類型如虛擬functiosn:使用mpl :: inherit_linearly定義接口的含義

class AbstractHandler 
{ 
public: 
    virtual void handleMessage(const MessageType1& msg) =0; 
    virtual void handleMessage(const MessageType2& msg) =0; 
    virtual void handleMessage(const MessageType3& msg) =0; 
    virtual void handleMessage(const MessageType4& msg) =0; 
}; 

和實現處理函數,然後創建派生具體類:

class ConcreteHandler : public AbstractHandler 
{ 
public: 
    virtual void handleMessage(const MessageType1& msg); 
    virtual void handleMessage(const MessageType2& msg); 
    virtual void handleMessage(const MessageType3& msg); 
    virtual void handleMessage(const MessageType4& msg); 
}; 

如果新消息添加到系統AbstractHandler必須與所有派生類型一起更新。

或者我可以在mpl序列中保存所有支持的消息類型,並使用mpl::inherit_linearly來生成抽象基類。

(注:我已經在使用中的代碼的其他地方的消息類型的mpl::vector。)

e.g:

typedef mpl::vector< MessageType1, MessageType2, 
        MessageType3, MessageType4 > message_types; 

template< class Message > 
class Wrapper 
{ 
public: 
    virtual void handleMessage(const Message& msg) = 0; 
protected: 
    ~Wrapper(){} 
}; 

class AbstractHandler 
    : public mpl::inherit_linearly< message_types 
            , mpl::inherit< mpl_1, Wrapper<mpl::_2> > 
            >::type 
{ 
public: 
    virtual ~AbstractHandler() {} 
}; 

混凝土處理程序然後從AbstractHandler派生。這意味着無論何時將新消息類型添加到系統中,只需更改mpl::vector<types...> message_types序列即可添加新的handleMessage函數到派生類。

在我看來,這降低長期維護,因爲AbstractHandler將自動擁有在mpl::vector message_types

的所有郵件純虛函數在性能方面有什麼缺點,使用這種方法?

使用mpl::inherit_linearly生成抽象基類有什麼含義?

回答

3

我以前做過類似的代碼(今天我又做了一遍)。

除繼承引起的費用外,沒有其他費用。主要是因爲最終類型是在編譯時確定的,而不是運行時。

但是,相對於消息類型列表大小,這顯然會使編譯時間更長。 如果像我一樣,你還要編寫一個消息分派器類(可以將任何東西分派給這種類型的任何處理程序),那麼在編譯時就會花費很多。

否則,這是很好的。

只要理解這種設置的含義:處理的消息列表是在編譯時定義的,而不是運行時定義的。由於使用要求,某些事件系統是運行時。所以請確保它是你想要的用例。

+0

感謝您對此的確認。我現在有一個工作解決方案,它是客戶端服務在處理消息時使用的API的一部分。到目前爲止,所有像API這樣的用戶...... MPL肯定有助於生成健壯的代碼...... – mark

+0

在用戶方面,它雖然有一些缺點:不太明顯的功能必須被定義。一個好的(最近的)編譯器會發出一個明確的消息,所以我猜這沒關係。如果有辦法強制用戶明確地覆蓋這些功能(以確保他們不犯錯誤),那也會更好。 – Klaim