解决涉及C ++状态机的前向声明问题

问题描述 投票:2回答:1

我最近中断后回到了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方法,该方法将调用下一个状态的构造函数。

由于循环依赖,我无法调用构造函数,因为它是无法预定义“问题”状态的两个构造函数。

我看了this文章,而模板方法似乎是理想的解决方案-但它不能编译,而且我对模板的了解还很有限...

[我的另一个想法是尝试将Helper类引入子类状态,通过多重继承,看是否可以指定基类的构造函数并引用了状态子类的构造函数。但我认为那是相当雄心勃勃...

最后,直接实施工厂方法设计模式是最好的方法解决整个问题?

c++ design-patterns circular-dependency forward-declaration state-pattern
1个回答
4
投票

您可以在类定义之外定义成员函数,例如,

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

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

定义依赖于更高类定义的成员函数之后定义那些类。仅当您在头文件中定义类的成员函数outside时,才需要inline关键字。

此外,为什么只在函数中使用new DH();您到处都在泄漏内存!

© www.soinside.com 2019 - 2024. All rights reserved.