Я создаю конечный автомат, в нескольких состояниях которого он переключается в новое (следующее) состояние в методе enter()
.Состояния - это unique_ptr
объекты, которые создаются по мере необходимости и передаются машине.
Поскольку некоторые состояния переключаются на следующее состояние в методе enter()
(таким образом, при использовании), я обеспокоен возможными проблемами здесь - когда текущее состояние вызывает set_state()
, конечный автомат назначает новое состояниеего член state
, таким образом, теряет единственный указатель на состояние, из которого был сделан этот вызов.
Ниже приведен пример моего беспокойства - единственный unique_ptr
для obj A и B установлен на Cв то время как рекурсивно вызывает это действие от A, а затем B. Является ли это надежным?Это вызовет какие-либо проблемы?
#include <memory>
#include <iostream>
class IState;
class IStateMachine {
public:
virtual ~IStateMachine() = default;
virtual void set_state(std::unique_ptr<IState> new_state) = 0;
};
class IState {
public:
virtual ~IState() = default;
virtual void enter(IStateMachine&) = 0;
};
class StateC : public IState {
public:
void enter(IStateMachine&) override {
std::cout << __func__ << ": StateC - start" << std::endl;
std::cout << __func__ << ": StateC - end" << std::endl;
}
};
class StateB : public IState {
public:
void enter(IStateMachine& sm) override {
std::cout << __func__ << ": StateB - start" << std::endl;
sm.set_state(std::make_unique<StateC>());
std::cout << __func__ << ": StateB - end" << std::endl;
}
};
class StateA : public IState {
public:
void enter(IStateMachine& sm) override {
std::cout << __func__ << ": StateA - start" << std::endl;
sm.set_state(std::make_unique<StateB>());
std::cout << __func__ << ": StateA - end" << std::endl;
}
};
class StateMachine : public IStateMachine {
public:
void start() {
set_state(std::make_unique<StateA>());
}
void set_state(std::unique_ptr<IState> new_state) {
state_ = std::move(new_state);
state_->enter(*this);
}
std::unique_ptr<IState> state_;
};
int main()
{
StateMachine sm;
sm.start();
}
Вывод кода:
enter: StateA - start
enter: StateB - start
enter: StateC - start
enter: StateC - end
enter: StateB - end
enter: StateA - end
Редактировать 1:
Основная идея заключается в следующемчто состояния создаются по мере необходимости и автоматически уничтожаются после того, как они больше не нужны.Ограничение состоит в том, что состояние может выполнять некоторую работу в своем методе enter()
, а затем в конце этого метода переключать конечный автомат в следующее состояние.
Редактировать 2:
Я не удаляю объект явно.Мой вопрос больше касается времени жизни объекта, на который указывает unique_ptr
в случае, когда новый объект назначен этому unique_ptr
из собственного метода объекта (рекурсивно) (см. Пример кода).