我正在尝试一个非常简单的FSM,在入口和出口处都有动作。流行的(?)示例传递原始指针并使用手动资源管理(例如https://refactoring.guru/design-patterns/state/cpp/example)
我的目标是使用自动化的资源管理和简单的界面。所以我尝试使用模板。它的工作和界面是OK-ish
class Fsm;
class State {
public:
virtual ~State() = default;
void SetFsm(Fsm* fsm) { fsm_ = fsm; }
virtual void Enter() = 0;
virtual void Exit() = 0;
protected:
// to allow state changes
Fsm* fsm_{ nullptr };
};
class Fsm {
public:
template <class T>
void TransitionTo() {
if (state_ != nullptr) {
// if switching to same state, do nothing
const auto temp = std::make_unique<T>();
if (dynamic_cast<T*>(state_.get()) != nullptr) { return; }
state_->Exit();
}
state_ = std::make_unique<T>();
state_->SetFsm(this);
state_->Enter();
}
private:
std::unique_ptr<State> state_;
};
在定义了class MyState1
和class MyState2
之后,可以将其称为
const auto my_object = std::make_unique<Fsm>();
my_object->TransitionTo<MyState1>();
my_object->TransitionTo<MyState2>()
但它不允许在构造时传递状态,因为模板化的构造函数不是一个东西。所以我创建了这个构造函数
Fsm(std::unique_ptr<State> state = nullptr) : state_(std::move(state)) {}
但结果就是
const auto my_object = std::make_unique<Fsm>(std::make_unique<MyState1>());
有什么建议如何使它成为一个更简单的构造函数吗?关于使用模板完成这项任务,有什么一般性的说明吗?
1条答案
按热度按时间hfwmuf9z1#
如果接口和可读性是您唯一关心的问题,并且您想摆脱编写长行的嵌套函数,那么您可以简单地实现工厂模式。
例如:
由于现在你不能直接创建FSM类,所以你不得不使用一个更简单/直观的界面的工厂。
它还允许你传递额外的参数来构建你的State类
=====