请求从 'std::unique_ptr<derived, std::default_delete<derived> >' 转换为非标量类型 'std::unique_ptr<base>'|
conversion from 'std::unique_ptr<derived, std::default_delete<derived> >' to non-scalar type 'std::unique_ptr<base>' requested|
我目前正在使用网络上的多个资源为游戏制作状态机。
但是,当我尝试创建一个 State 并将其放入 StateMachine 时,我的问题就来了。
错误在 StateGameMenu.cpp,在 sendConnexion.
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/(这是对其他代码的更改)。
在这段代码中,将 State 赋予 StateMachine 的方式与我的非常相似,但它在我的情况下不起作用,我不知道为什么。
是的,我可以在这个上克隆我的代码,但我更喜欢自己做。
我希望我的 post 不会太长和模糊,因为我自己真的很困惑。 (而且我没有找到任何东西来回答我的问题。)
感谢您阅读整篇 post 以及您抽出宝贵的时间! (抱歉我的英语不好)。
无法创建 StateGamePlay
的实例,因为 State
构造函数是私有的。
class StateGamePlay : State // default private inheritance
应该是
class StateGamePlay : public State
我目前正在使用网络上的多个资源为游戏制作状态机。 但是,当我尝试创建一个 State 并将其放入 StateMachine 时,我的问题就来了。 错误在 StateGameMenu.cpp,在 sendConnexion.
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/(这是对其他代码的更改)。 在这段代码中,将 State 赋予 StateMachine 的方式与我的非常相似,但它在我的情况下不起作用,我不知道为什么。 是的,我可以在这个上克隆我的代码,但我更喜欢自己做。
我希望我的 post 不会太长和模糊,因为我自己真的很困惑。 (而且我没有找到任何东西来回答我的问题。) 感谢您阅读整篇 post 以及您抽出宝贵的时间! (抱歉我的英语不好)。
无法创建 StateGamePlay
的实例,因为 State
构造函数是私有的。
class StateGamePlay : State // default private inheritance
应该是
class StateGamePlay : public State