从'std :: unique_ptr <派生,std :: default_delete <derived =“”>>'到非标量类型'std :: unique_ptr <base />'的转换|

时间:2019-01-03 05:41:53

标签: c++ state c++17 unique-ptr

我目前正在使用网络上的多种资源为游戏制作StateMachine。 但是,当我尝试创建一个州将其放入StateMachine时,我的问题就来了。 错误发生在sendConnexion的StateGameMenu.cpp中。

StateGameMenu.h

#ifndef STATEGAMEMENU_H
#define STATEGAMEMENU_H
#include <TGUI/TGUI.hpp>

#include <SFML/Graphics.hpp>
#include <SFML/Network.hpp>

#include <memory>
#include <thread>

#include "Log.h"
#include "Client.h"
#include "Personnage.h"
#include "State.hpp"

class StateMachine;

class StateGameMenu : public State
{
    public:
        StateGameMenu(Context& context);

        virtual ~StateGameMenu();

    protected:
        void sendConnexion(tgui::EditBox::Ptr username, tgui::EditBox::Ptr password);
        void loadGUI();

    private:
};

#endif // STATEGAMEMENU_H

StateGameMenu.cpp,我的错误在哪里。

#include "StateGameMenu.h"
#include "StateGamePlay.h"

#include "StateMachine.h"

StateGameMenu::StateGameMenu(Context& context) : State(context)
{
    //ctor
}
void StateGameMenu::sendConnexion(tgui::EditBox::Ptr username, tgui::EditBox::Ptr password)
{
    m_context.Client->connexion(username->getText().toAnsiString(), password->getText().toAnsiString());
    if(m_context.Client->estConnecte())
    {
        ///The line below is the line triggering an error. 
        std::unique_ptr<State> temp = StateMachine::build<StateGamePlay>(m_context); ///The problem is here.
        m_context.Machine->askPush(std::move(temp), true);
    }
}
void StateGameMenu::loadGUI()
{
    /* Some GUI Stuff ... */

    button->connect("pressed", StateGameMenu::sendConnexion, this, editBoxUsername, editBoxPassword);
}
StateGameMenu::~StateGameMenu(){}

错误是:

conversion from 'std::unique_ptr<StateGamePlay, std::default_delete<StateGamePlay> >' to non-scalar type 'std::unique_ptr<State>' requested|

对于我来说,理解函数“ build”的输出为什么不只是一个“ std :: unique_ptr”实际上是非常困难的。

StateGamePlay.h

#ifndef STATEGAMEPLAY_H
#define STATEGAMEPLAY_H

#include "State.hpp"

class StateMachine;

class StateGamePlay : State
{
    public:
        StateGamePlay(Context& context);

        virtual ~StateGamePlay();

    protected:

    private:
};

#endif // STATEGAMEPLAY_H

StateGamePlay.cpp

#include "StateGamePlay.h"

#include "StateMachine.h"

StateGamePlay::StateGamePlay(Context& context) : State(context)
{
    //ctor
}

有关更多信息: StateMachine.h

#ifndef STATEMACHINE_H
#define STATEMACHINE_H

#include <SFML/Graphics.hpp>

#include <stack>
#include <memory>

#include "Log.h"
#include "Context.h"

class State;

class StateMachine
{
    public:
        typedef std::unique_ptr<State> StatePtr;


        StateMachine();
        void askPush(StatePtr state, bool isReplacing = true);
        void askPop();

        template <typename T>
        static std::unique_ptr<T> build( Context& context );

        void processStateChanging();

        virtual ~StateMachine();

    protected:
        void push();
        void pop();
        void resume();
        void pause();

        void modifyState();

        std::stack<StatePtr> m_States;
        bool m_isReplacing;
        bool m_isChanging;
        bool m_isDeleting;
        StatePtr m_FutureChangingState;

    private:
};

#include "State.hpp"

template <typename T>
std::unique_ptr<T> StateMachine::build( Context& context )
{
    //return  std::unique_ptr<T>( new T(context) );
    return std::make_unique<T>( context );
}

#endif // STATEMACHINE_H

问题似乎直接与模板函数有关,但是我没有发现那部分有什么问题,并且调用似乎写得正确。

State.hpp

#ifndef STATE_H
#define STATE_H

#include <SFML/Graphics.hpp>
#include <TGUI/TGUI.hpp>

#include <memory>

#include "Client.h"
#include "Context.h"

class StateMachine;

class State
{
    public:

        State(Context& context);
        State ( const State& ) = delete;
        State& operator= ( const State& ) = delete;

        void pause() {inPause = true;};
        void resume() {inPause = false;};

        virtual ~State();

    protected:
        bool inPause;
        Context m_context;

    private:
};

#endif // STATE_H

Context.h

#ifndef CONTEXT_H_INCLUDED
#define CONTEXT_H_INCLUDED

#include <SFML/Graphics.hpp>
#include <TGUI/TGUI.hpp>

#include <memory>

#include "Client.h"

class StateMachine;

struct Context
{
    typedef std::shared_ptr<sf::RenderWindow> WindowPtr;
    typedef std::shared_ptr<StateMachine> MachinePtr;
    typedef std::shared_ptr<tgui::Gui> GuiPtr;
    typedef std::shared_ptr<Client> ClientPtr;

    Context(WindowPtr window, MachinePtr machine, GuiPtr gui, ClientPtr client);
    WindowPtr Window;
    MachinePtr Machine;
    GuiPtr Gui;
    ClientPtr Client;
};
Context::Context(WindowPtr window, MachinePtr machine, GuiPtr gui, ClientPtr client) :
Window(window), Machine(machine), Gui(gui), Client(client)
{ }

#endif // CONTEXT_H_INCLUDED

最后,我编写该部分的主要资源之一是eXpl0it3r的https://github.com/eXpl0it3r/SmallGameEngine/tree/master/(这是对其他代码的更改)。 在此代码中,将状态授予StateMachine的方式实际上与我的类似,但是在我的情况下它不起作用,我也不知道为什么。 是的,我可以在此代码上克隆我的代码,但我更愿意自己完成代码。

我希望我的帖子不会太长且模糊,因为我自己真的很困惑。 (而且我没有找到任何答案。) 多谢您阅读本文全文,以及您的时间! (对不起,我英语不好。)

1 个答案:

答案 0 :(得分:1)

由于StateGamePlay构造函数是私有的,因此无法创建State的实例。

class StateGamePlay : State // default private inheritance

应该是

class StateGamePlay : public State