【发布时间】:2013-09-18 00:12:45
【问题描述】:
编辑:好的,正如我现在所看到的,这改变了很多情况,所以更精确的情况是这样的:
我目前的层次结构有点类似于这样:
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...>();
我在尝试强制转换对象和调用函数时遇到了 Visual Studio 错误:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.
通过派生对 IBase 接口的所有调用都可以正常工作,但是当我尝试将派生转换为 IDerived 时,调用任何函数时都会出错:
IDerived* d = (IDerived*)derived;
d->Bar(); <- boom error ;)
我猜这样的转换是非法的,但是我怎样才能转换指针,以便我可以访问 IDerived 接口方法(最好没有 dynamic_cast,如果存在的话,我更喜欢一个好的和可移植的 hack ;))?是否有可能以某种方式计算指针的偏移量,以便使用正确的 vtable 并且一切正常?
我已经编程了很长时间,但我总是避开那些对具有大量界面和模板的工程系统的幻想,而现在我注定要自己制作一个。
编辑:现在你可以看到这变得棘手和困难。我不知道我得到的 Derived 的确切类型,因为它是模板化的,函数 CreateDerived 也是模板化的并返回接口。
另外,要求之一是不要使用dynamic_cast(项目中禁用了RTTI)
【问题讨论】:
-
IDerived* d = (IDerived*)d;- 错字?第二个d应该是derived吗? -
谢谢,已经注意到并修复了;)
-
另外,你不应该在 C++ 中使用 C 风格的强制转换,而应该使用 C++ 风格的强制转换,例如
static_cast或dynamic_cast -
看,这是上次编辑后的全新问题! :P
-
是的,很抱歉我忽略了这里的角色模板。就像我说的,我讨厌所有那些离奇复杂的解决方案,在这种情况下我找不到更好的选择。
标签: c++ inheritance upcasting