簡體   English   中英

解決涉及 C++ 狀態機的前向聲明問題

[英]Resolving a Forward Declaration Issue Involving a State Machine in C++

我最近在中斷后返回 C++ 開發,並且對狀態設計模式的實現有疑問。 我正在使用香草模式,完全按照 GoF 的書。

我的問題是狀態機本身基於用作嵌入式系統一部分的某些硬件 - 因此設計是固定的,無法更改。 這導致兩個狀態之間的循環依賴(特別是),我正在嘗試解決這個問題。 這是簡化的代碼(請注意,我嘗試像往常一樣使用標頭來解決此問題,但仍然存在問題 - 我在此代碼片段中省略了它們):

#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 方法來進行的,該方法調用下一個狀態的構造函數。

由於循環依賴,我無法調用構造函數,因為不可能預定義“問題”狀態的兩個構造函數。

我看了這篇文章,模板方法似乎是理想的解決方案 - 但它不能編譯,而且我對模板的了解相當有限......

我的另一個想法是嘗試通過多重繼承向子類狀態引入 Helper 類,以查看是否可以指定基類的構造函數並引用狀態子類的構造函數。 但我認為那是相當雄心勃勃的......

最后,直接實現工廠方法設計模式是否是解決整個問題的最佳方式?

您可以在類定義之外定義成員函數,例如,

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

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

定義一個靠后的類定義這些類的定義,成員函數。 僅當您在頭文件中的類之外定義成員函數時,才需要inline關鍵字。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM