为什么将对象从一个智能指针移至另一个原因崩溃



我对智能指针没有太多经验。我写简单的状态堆栈,并且对此功能有问题:

void StateStack::changeState(StatesType type)
{
    currentState = std::move(statesFactory(type));
}

这是对象的最后一个指针,因此智能指针删除对象,我会崩溃。

状态是具有虚拟函数的基类,Mainmenu和LoadingScreen从状态继承。

 int main()
    {
        Application application;
        application.run();
    }

Application::Application()
    : window(sf::VideoMode(1024, 768), "Test", sf::Style::Close),
    stateStack(State::Context(window))//...
{
}

StateStack::StateStack(State::Context settedContext):
    context(settedContext)
{
    currentState = statesFactory(StatesType::GameLoading);
}
std::unique_ptr<State> StateStack::statesFactory(StatesType type)
{
    std::unique_ptr<State> state;
    if (type==StatesType::GameLoading)      //etc. TODO
    {
        state.reset(new GameLoadingState(std::shared_ptr<StateStack>(this), context));
    }
    else if (type == StatesType::MainMenu)
    {
        state.reset(new MainMenuState(std::shared_ptr<StateStack>(this), context));
    }
    return state;
}
void GameLoadingState::update(sf::Time dt)
{
    //...
    if (timeSinceStart.asSeconds() > 5)
    {
        stack->changeState(StatesType::MainMenu);
    }
}
    class State
    {
    public:
        State(std::shared_ptr<StateStack> parent, Context settedContext);
        virtual void handleEvent(const sf::Event& event) = 0;
        //virtual ~State();
    protected:
        std::shared_ptr<StateStack> stack;
    private:
        Context context;
    };

最初状态有虚拟破坏者,那里发生了崩溃。我认为这是不必要的,现在移动是问题触发。

预先感谢您,如果您指出我需要的内容,我可以向您发送更多代码。

当您从原始指针中构造共享指针时,共享指针将把自己(以及由其制成的任何副本)视为原始指针的"所有权组",并负责为了删除。

因此,您不想多次从相同的原始指针中构造共享指针。在这里,您似乎要多次从this构建共享指针。每个这样的结构都会认为自己是所有者 - 因此您将在同一指针上获得多个删除。

正如 @jarod42所指出的那样,有enable_shared_from_this可以用来解决想要将其他共享指针提供给已经由共享指针管理的东西的特定模式:

http://en.cppreference.com/w/cpp/memory/enable_shared_from_this

如果我使用enable_shared_from__this和后来的shared_from_this(),我会得到bad feek_ptr异常。我必须至少有一个指向stateStack的指针。

是。请参阅上面链接中的示例。如果让共享指针设置您想要的方式感到"尴尬",也许您应该重新考虑设计。

如果我们用英语说,那么您现在拥有的目的似乎是:"当StateStack中的最后一个状态消失时,StateStack将自动销毁。" 是合理/必要?

您的程序中有多少个StateStack S?在终生管理方面,您能做到这一点,以便您确定堆栈超过了各州吗?然后,您可以只使用普通参考来指向堆栈,并在确定状态未被使用后销毁堆栈。

如果您习惯于以垃圾收集的语言进行编程,则可能会尝试过度使用shared_ptr。考虑可能在可能的情况下思考所有权的更等级的方式。

相关内容

  • 没有找到相关文章

最新更新