Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过基指针将派生类强制转换到其中一个基_C++_Inheritance_Upcasting - Fatal编程技术网

C++ 通过基指针将派生类强制转换到其中一个基

C++ 通过基指针将派生类强制转换到其中一个基,c++,inheritance,upcasting,C++,Inheritance,Upcasting,编辑:好的,正如我现在看到的,这会改变很多情况,因此更精确的情况如下: 我目前的层次结构与此类似: class IBase() { virtual void Foo() = 0; }; class Base() : public IBase { virtual void Foo() { } }; class IDerived() { virtual void Bar() = 0; }; template<typename TT, typename TB, typename... TI

编辑:好的,正如我现在看到的,这会改变很多情况,因此更精确的情况如下:

我目前的层次结构与此类似:

class IBase() { virtual void Foo() = 0; };

class Base() : public IBase { virtual void Foo() { } };

class IDerived() { virtual void Bar() = 0; };

template<typename TT, typename TB, typename... TI>
class Derived : public Base, public IDerived { virtual void Bar() {}};

template<typename TT, typename TB, typename... TI>
IBase* CreateDerived() { return new Derived(); }

IBase* derived = CreateDerived<some types...>();
通过派生调用IBase接口的所有调用都可以正常工作,但当我尝试将派生转换为IDerived时,调用任何函数都会出错:

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.  
IDerived* d = (IDerived*)derived;
d->Bar(); <- boom error ;) 
IDerived*d=(IDerived*)派生;

d->Bar() 您正在执行交叉播放
IBase
IDerived
是不相关的。您需要先强制转换为
派生的
,然后再转换为
IDerived的
。如果您使用的是
static\u cast
而不是C cast,编译器会在编译时为您捕捉到这一点

我假设您知道,
IBase
实际上是一个
派生的
,因为您使用了C转换,但是如果您不这样做,那么您也可以使用
dynamic_cast
安全地执行交叉转换

编辑:如果您不能使用RTTI并且不知道对象的动态类型,那么虚拟继承和
dynamic\u cast
将退出窗口。当您调用
CreateDerived
时,看起来您确实知道对象的动态类型(因为它的模板参数),因此您可以有一个
std::map
,然后在
CreateDerived()之后
call您可以
static\u cast
IBase*
转换为
Derived*
,然后将指针作为键和值插入到映射中


只需启用RTTI;这越来越复杂了<代码>IDerived*d=(IDerived*)d-输入错误?第二个
d
应该是
派生的吗?
谢谢,alredy注意到了这一点并修复了;)此外,C++中不应该使用C风格的转换,而是使用C++风格的转换,如<代码> StasyType > <代码>或<代码> Dyjic Skys> /Cord>,这是最后一次编辑后的一个全新问题!是的,很抱歉我忽略了角色模板在这里的作用。就像我说的,我讨厌所有那些奇怪的复杂的解决方案。在这种情况下,我看不到更好的选择。谢谢你的回答,但这不是那么简单,我应该从一开始就澄清;)请看地图edit@AdrianLis如果您不能使用
dynamic_cast
,那么从
IBase
IDerived
通常是没有安全的方法的。感谢您的提示,我将研究EDIT2建议,看看它是否解决了更大规模场景中的问题;)我会让你知道,从非常简短的测试,似乎中级班解决了这个问题。目前还不确定它将如何与样板文件的其余部分一起进行,但肯定它解决了所描述的问题,因此我将您的答案标记为解决方案。谢谢;)
class IBase { virtual void Foo() = 0; };

class Base : public IBase { virtual void Foo() { } };

class IDerived { virtual void Bar() = 0; };

class BaseAndDerived : public Base, public IDerived { };

template<typename TT, typename TB, typename... TI>
class Derived : public BaseAndDerived { virtual void Bar() {}};