2010-06-15 52 views
2

我最近在中斷後返回C++開發,並且有關於狀態設計模式的 實現的問題。我正在使用香草模式,正如GoF書中的 。解決涉及C++中狀態機的轉發聲明問題

我的問題是,狀態機本身是基於一些硬件作爲 嵌入式系統的一部分 - 所以設計是固定的,不能改變。這導致了兩個狀態(特別是)之間的循環依賴關係 ,我試圖通過 解決此問題。下面是簡化的代碼(注意,我試圖用 頭像往常一樣去解決這一點,但仍然有問題 - 我省略了他們在此代碼段):

#include <iostream> 
#include <memory> 

using namespace std; 

class Context 
{ 
public: 
    friend class State; 

    Context() { } 

private: 
    State* m_state; 
}; 

class State 
{ 
public: 
    State() { } 

    virtual void Trigger1() = 0; 
    virtual void Trigger2() = 0; 
}; 

class LLT : public State 
{ 
public: 
    LLT() { } 
    void Trigger1() { new DH(); } 
    void Trigger2() { new DL(); } 
}; 


class ALL : public State 
{  
public: 
    ALL() { } 
    void Trigger1() { new LLT(); } 
    void Trigger2() { new DH(); } 
}; 

// DL needs to 'know' about DH. 
class DL : public State 
{   
public: 
    DL() { } 
    void Trigger1() { new ALL(); } 
    void Trigger2() { new DH(); } 
};  

class HLT : public State 
{ 
public: 
    HLT() { } 
    void Trigger1() { new DH(); } 
    void Trigger2() { new DL(); } 
}; 

class AHL : public State 
{ 
public: 
    AHL() { } 
    void Trigger1() { new DH(); } 
    void Trigger2() { new HLT(); } 
}; 

// DH needs to 'know' about DL. 
class DH : public State 
{ 
public: 
    DH() { } 
    void Trigger1() { new AHL(); } 
    void Trigger2() { new DL(); } 
}; 


int main() 
{ 
    auto_ptr<LLT> llt (new LLT); 
    auto_ptr<ALL> all (new ALL); 
    auto_ptr<DL> dl (new DL); 
    auto_ptr<HLT> hlt (new HLT); 
    auto_ptr<AHL> ahl (new AHL); 
    auto_ptr<DH> dh (new DH); 

    return 0; 
} 

的問題基本上是在國家模式狀態轉換由 調用Context類中的ChangeState方法進行,該方法調用下一個狀態的構造函數 。

由於循環依賴關係,我無法調用構造函數,因爲它不可能預先定義「問題」狀態的兩個構造函數,因爲它不是 。

我看了一下this文章,以及這似乎是理想的解決方案模板方法 - 但它並沒有編譯和我的模板知識是相當有限的......

其他想法,我必須嘗試通過多重繼承向子類狀態 引入一個Helper類,以查看是否可以指定基類的構造函數 並具有對狀態子類的構造函數的引用。但我認爲這是寧願 宏大...

最後,將工廠方法設計模式直接implmentation是最好的方式 來解決整個問題?

回答

4

可以定義成員函數的類定義的外,例如,

class DL : public State 
{ 
public: 
    void Trigger2(); 
}; 

inline void DL::Trigger2() { new DH(); } 

定義依賴於稍後類定義這些類被定義後的成員函數。 inline關鍵字僅在定義頭文件中該類的以外的成員函數時是必需的。

順便說一句,爲什麼你只在你的函數中使用new DH();你到處都在向內存泄漏!

+0

嗨,詹姆斯!很多很多非常感謝您的快速答案 - 完美地工作:-)道歉,我忘記了在代碼片段中的每個new()調用中進行相應的刪除操作。 – HypersonicNinja 2010-06-15 13:50:16

+0

@hyper:沒問題;我只是想確保它不是你函數中的_only_事物::-) – 2010-06-15 13:51:30