是否可以在没有动态多态性的情况下在 C++ 中实现状态设计模式?

Posted

技术标签:

【中文标题】是否可以在没有动态多态性的情况下在 C++ 中实现状态设计模式?【英文标题】:Is it possible to implement the state design pattern in C++ without dynamic polymorphism? 【发布时间】:2021-09-13 15:01:27 【问题描述】:

假设我有以下 C++ 代码

class ControlAlgorithm 

public:
    virtual void update() = 0;
    virtual void enable() = 0;
    virtual void disable() = 0;
;

class Algorithm_A : public ControlAlgorithm 

public:
    void update();
    void enable();
    void disable();
;

class Algorithm_B : public ControlAlgorithm 

public:
    void update();
    void enable();
    void disable();
;

Algorithm_A algorithm_A;
Algorithm_B algorithm_B;
ControlAlgorithm *algorithm;

假设我想在运行时根据一些外部事件在algorithm_Aalgorithm_B 之间切换(基本上我要实现状态设计模式)。所以algorithm 指针指向algorithm_Aalgorithm_B 对象。我的问题是是否有任何方法可以实现在运行时动态切换算法的能力,而无需虚拟方法 通用接口,例如奇怪的反复出现的模板模式?

【问题讨论】:

你为什么需要它?当我们知道需要这样做时,可能会更容易回答。例如,您可以有函数映射,但这只是带有额外步骤的动态多态性。只有2个州可供选择吗? switch 可能是个不错的选择。 是的,不要使用状态模式。我总是觉得它太冗长,导致太多类,并且很难跟踪实际行为。在它的基础上,FSM 是一个功能问题,我通常以基于表的方法来解决它,在这种状态下,使用这个触发器,调用那个响应函数并移动到下一个状态。对于小型机器来说,一个开关盒就足够了。 【参考方案1】:

您可以使用composition over inheritance。例如,如下所示。

#include <iostream>
#include <functional>

struct control_algorithm 
    const std::function<void()> update;
    const std::function<void()> enable;
    const std::function<void()> edit;
;

control_algorithm make_algorithm_A() 
    return 
        []()  std::cout << "update A\n"; ,
        []()  std::cout << "enable A\n"; ,
        []()  std::cout << "edit A\n"; ,
    ;


control_algorithm make_algorithm_B() 
    return 
        []()  std::cout << "update B\n"; ,
        []()  std::cout << "enable B\n"; ,
        []()  std::cout << "edit B\n"; ,
    ;


int main()

    auto algorithm_A = make_algorithm_A();
    auto algorithm_B = make_algorithm_B();
    auto control = algorithm_A;
    //auto control = algorithm_B;

【讨论】:

现在std::function内部隐藏了动态多态性 这是否重要取决于 OP 提出问题的原因,但无论如何您都可以使用函数指针做同样的事情。

以上是关于是否可以在没有动态多态性的情况下在 C++ 中实现状态设计模式?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在没有可启动应用程序的情况下在 Apple Watch 上实现动态通知?

我可以在没有 POST 的情况下在 python 中实现 Web 用户身份验证系统吗?

我可以在没有自己的后端服务器的情况下在 React 中实现 Stripe 结账吗?

有没有办法在没有 for 循环的情况下在 numpy 中实现重复?

如何在没有 Flash 的情况下在 Firefox 中实现复制到剪贴板。需要实施[重复]

如何在没有选择按钮的情况下在 GridView 中实现全行选择?