无法将超类转换为子类
Can't cast superclass to subclass
我目前正在我的游戏和渲染引擎之间编写一个抽象层。不幸的是,我遇到了一个问题:我似乎无法将超类(抽象接口)转换为子类(具体引擎的实现)。这是我的代码:
IInitationSettings.h
class IInitationSettings {};
OxygineInitiationSettings.h
#include "IInitiationSettings.h"
#include "core/oxygine.h"
class OxygineInitiationSettings : public IInitationSettings, public oxygine::core::init_desc {
public:
OxygineInitiationSettings(const char* title, bool vsync, bool fullscreen, int width, int height);
};
OxygineInitiationSettings.cpp
#include "OxygineInitiationSettings.h"
OxygineInitiationSettings::OxygineInitiationSettings(const char* title, bool vsync, bool fullscreen, int width, int height) : oxygine::core::init_desc() {
this->title = title;
this->vsync = vsync;
this->fullscreen = fullscreen;
this->w = width;
this->h = height;
}
抽象初始化方法:
static void init(IInitiationSettings& initSettings);
void GraphicsFactory::init(IInitiationSettings& initSettings){
#ifdef USE_OXYGINE_RENDERING
OxygineInitiationSettings settings = initSettings; //Does not work
oxygine::core::init_desc desc = initSettings; // Does not work
oxygine::core::init((oxygine::core::init_desc)((OxygineInitiationSettings)initSettings)); //Does not work
#endif
}
如何将抽象接口转换为具体实现?我也想添加一个 newInitiationSettings-Method,它将 return 一个 IInitiationSettings 对象,我将把它传递给 init 方法,以便获得干净的代码。
(我希望我的游戏代码看起来像这样:
GraphicsFactory::init(GraphicsFactory::newInitiationSettings(args));
)
有什么想法吗?
Dynamic_cast 可以从虚拟 class 执行,即具有虚拟方法的 class。只需像这样添加 dummy() 方法:
class IInitationSettings {
virtual void dummy() {}
};
并从隐式转换为动态转换:
void GraphicsFactory::init(IInitationSettings& initSettings) {
OxygineInitiationSettings settings =
dynamic_cast<OxygineInitiationSettings&>(initSettings); //Does indeed work
}
会解决问题。
这里的根本错误是试图在您的抽象 init 方法中将对象本身转换为不同的类型。向上转换(即朝向基数 class)导致 object slicing,因为它只复制基数 class 的数据。这通常很糟糕,但向下投射可能是不可能的。所以编译器不会让你。
您真正想做的是在引用或指针级别工作。粗略地说,引用是指针的语法糖,指向对象的指针可替代指向其基类 class 之一的指针。这就是为什么您可以通过 base&
类型的参数传递 derived
。但是当你试图找回你的 derived
时,你必须要 derived&
或 derived*
。在您的情况下,这看起来更像是其中之一:
static_cast<OxygineInitiationSettings&>(initSettings) // or
dynamic_cast<OxygineInitiationSettings&>(initSettings)
或者,如果你需要一个指针,也许是这样的:
static_cast<OxygineInitiationSettings*>(&initSettings) // or
dynamic_cast<OxygineInitiationSettings*>(&initSettings)
如果您确定 initSettings
将引用一个 OxygineInitiationSettings
实例,您可以而且应该使用 static_cast
而不是 dynamic_cast
。如果您不确定,您应该变得确定或使用 dynamic_cast
而不是 static_cast
。请注意,动态引用转换将引发 std::bad_cast
异常,如果 initSettings
引用的实际对象实际上不是 [=18=,则动态指针转换将 return 为空指针].
我目前正在我的游戏和渲染引擎之间编写一个抽象层。不幸的是,我遇到了一个问题:我似乎无法将超类(抽象接口)转换为子类(具体引擎的实现)。这是我的代码:
IInitationSettings.h
class IInitationSettings {};
OxygineInitiationSettings.h
#include "IInitiationSettings.h"
#include "core/oxygine.h"
class OxygineInitiationSettings : public IInitationSettings, public oxygine::core::init_desc {
public:
OxygineInitiationSettings(const char* title, bool vsync, bool fullscreen, int width, int height);
};
OxygineInitiationSettings.cpp
#include "OxygineInitiationSettings.h"
OxygineInitiationSettings::OxygineInitiationSettings(const char* title, bool vsync, bool fullscreen, int width, int height) : oxygine::core::init_desc() {
this->title = title;
this->vsync = vsync;
this->fullscreen = fullscreen;
this->w = width;
this->h = height;
}
抽象初始化方法:
static void init(IInitiationSettings& initSettings);
void GraphicsFactory::init(IInitiationSettings& initSettings){
#ifdef USE_OXYGINE_RENDERING
OxygineInitiationSettings settings = initSettings; //Does not work
oxygine::core::init_desc desc = initSettings; // Does not work
oxygine::core::init((oxygine::core::init_desc)((OxygineInitiationSettings)initSettings)); //Does not work
#endif
}
如何将抽象接口转换为具体实现?我也想添加一个 newInitiationSettings-Method,它将 return 一个 IInitiationSettings 对象,我将把它传递给 init 方法,以便获得干净的代码。 (我希望我的游戏代码看起来像这样:
GraphicsFactory::init(GraphicsFactory::newInitiationSettings(args));
)
有什么想法吗?
Dynamic_cast 可以从虚拟 class 执行,即具有虚拟方法的 class。只需像这样添加 dummy() 方法:
class IInitationSettings {
virtual void dummy() {}
};
并从隐式转换为动态转换:
void GraphicsFactory::init(IInitationSettings& initSettings) {
OxygineInitiationSettings settings =
dynamic_cast<OxygineInitiationSettings&>(initSettings); //Does indeed work
}
会解决问题。
这里的根本错误是试图在您的抽象 init 方法中将对象本身转换为不同的类型。向上转换(即朝向基数 class)导致 object slicing,因为它只复制基数 class 的数据。这通常很糟糕,但向下投射可能是不可能的。所以编译器不会让你。
您真正想做的是在引用或指针级别工作。粗略地说,引用是指针的语法糖,指向对象的指针可替代指向其基类 class 之一的指针。这就是为什么您可以通过 base&
类型的参数传递 derived
。但是当你试图找回你的 derived
时,你必须要 derived&
或 derived*
。在您的情况下,这看起来更像是其中之一:
static_cast<OxygineInitiationSettings&>(initSettings) // or
dynamic_cast<OxygineInitiationSettings&>(initSettings)
或者,如果你需要一个指针,也许是这样的:
static_cast<OxygineInitiationSettings*>(&initSettings) // or
dynamic_cast<OxygineInitiationSettings*>(&initSettings)
如果您确定 initSettings
将引用一个 OxygineInitiationSettings
实例,您可以而且应该使用 static_cast
而不是 dynamic_cast
。如果您不确定,您应该变得确定或使用 dynamic_cast
而不是 static_cast
。请注意,动态引用转换将引发 std::bad_cast
异常,如果 initSettings
引用的实际对象实际上不是 [=18=,则动态指针转换将 return 为空指针].