在其成员函数返回之前,将对象删除是不确定的行为吗?

Is it undefined behavior to have an object be deleted before its member function returns?

本文关键字:不确定 删除 对象 函数 成员 返回      更新时间:2023-10-16

可能的重复:
C :删除此?

我正在尝试创建一个管理游戏状态的系统。

我当前设计的问题是,当我切换状态时,旧状态在控制转换为新状态之前已删除。

以下是我的代码的简化版本:

class StateManager;
class State
{
public:
    virtual void update(StateManager &manager)= 0;
    virtual ~State(){}
};

class StateManager
{
public:
    void setState(std::unique_ptr<State> && newState )
    {
        currentState = std::move(newState);
    }
    std::unique_ptr<State> currentState;
    void run()
    {
        currentState->update(*this);
    }
};

请注意,如果状态对象在更新方法中调用StateManager :: SetState,则会在一段时间内调用成员函数在刚刚被破坏的对象上。

此行为的一个完整示例是在http://ideone.com/whlzjl上。请注意,在FirstState ::更新返回之前,如何调用FirstState的破坏者。

这种不确定的行为是C 吗?如果是这样,我应该如何更改设计?

不,没关系,如果您小心:

没有问题,这是您在功能中所做的最后一件事。(delete this是一个常见的成语。)在这种特殊情况下,我通常认为State::update最好返回新的State(可以是this)。然后,在StateManager中调用它的代码将简单地将其分配给指针。

在这种情况下,请注意智能指针的语义。我使用侵入性共享指针进行了操作,但我怀疑当前的大多数智能指针都会在这里失败。另一方面,您在这里真的不需要明智的指针,所以为什么要添加复杂性。

据我所知,主要效果是this成为一个悬空的指针,因此访问字段,调用virtual方法或执行依赖运行时类型信息的dynamic_cast<T*>(this)之类的事情将结果在未定义的行为中。