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

时间:2012-11-02 23:04:11

标签: c++

  

可能重复:
  C++: Delete this?

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

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

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

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);
    }
};

请注意,如果State对象在update方法中调用StateManager :: setState,则会有一段时间在刚刚被销毁的对象上调用成员函数。

此行为的完整示例位于http://ideone.com/WHLzJL。注意在FirstState :: update返回之前如何调用FirstState的析构函数。

这是C ++中的未定义行为吗? 如果是这样,我该如何改变我的设计?

3 个答案:

答案 0 :(得分:7)

不,没关系,如果你小心:https://isocpp.org/wiki/faq/freestore-mgmt#delete-this

答案 1 :(得分:2)

没有问题,这是你在函数中做的 last 事情。 (delete this是一种常见的习惯用法。)但是,在这种特殊情况下,我通常认为State::update最好返回新的State(可能是this )。在StateManager中调用它的代码将简单地将其分配给指针。

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

答案 2 :(得分:0)

据我所知,主要影响是this成为悬空指针,因此访问字段,调用virtual方法或执行依赖于运行时的dynamic_cast<T*>(this)之类的操作类型信息会导致未定义的行为。