繁体   English   中英

没有RTTI的dynamic_cast

[英]dynamic_cast without RTTI

我的结构如下:

struct managed_object {
  virtual ~managed_object() { }
};

class trait1 {
  public: 
    virtual void myMethod() const = 0;
};

class trait2 {
  public: 
    virtual void myOtherMethod(int x) const = 0;
};

class MyType final : public managed_object, public trait1 {
 ...
};

class MyType2 final : public managed_object, public trait1, public trait2 {
 ...
};

class wrapper {
  private:
    managed_object* ptr;
  public:
    template<typename T> T* object() const { 
      return dynamic_cast<T*>(data.ptr); 
    }
};

因此,基本上我有一个managed_object基类,从该基类可以继承多个类型。 每个子类型都可以从特征的任何组合中继承,并且它们都是final因此我确定它们在继承方面不会有任何更深层次的了解。

该代码的工作要归功于RTTI,它承担了将所有东西粘合在一起的负担,但要付出一定的代价,否则

wrapper w = ...
trait* asTrait1 = w.object<trait1>;

将不起作用,因为managed_objecttrait1类型之间没有直接关系。

在我完整的代码中,我已经确定所有dynamic_cast都不会失败,因为我还有其他数据(示例中未显示),这为我提供了其他代码部分所需的RTTI。

鉴于此,假设我已经知道MyType类是从特定trait继承来的,是否有一种无需使用dynamic_cast和RTTI即可解决投问题的通用模式? 我试图找到一个聪明的解决方案,因为它是代码的沉重瓶颈。

没有RTTI, 就不能使用dynamic_cast 除了一些极端情况。

可以使用static_castreinterpret_cast (请不要使用),但是如果您弄错了,它就在身上-然后您将无法再测试nullptr以查看转换是否成功

首先,您必须使用static_cast reinterpret_cast并不是很适合此操作。

但是,为了使转换正常工作,您的程序需要知道运行的方向。 我的意思是,它需要知道从A投射到B必须采取的路径。 如果AB在相同的类层次结构中,这很简单:只需按照所述的类层次结构进行转换。

但是,如果您有:

struct C: A, B {};

并且这是AB之间的唯一关系, static_cast无法了解C (这是RTTI提供的信息的一种),因此由于AB并不真正相关,因此它无法执行static_cast

为了提供该路径,您必须使您的程序以某种方式知道它。 最简单的方法是模板wrapper

template<typename T>
class wrapper {
  managed_object* ptr;
public:
  template<typename Trait> Trait* object() const { 
    return static_cast<Trait*>(static_cast<T*>(ptr)); 
  }
};

然后:

MyType a;
wrapper<MyType> w{&a};
trait1* asTrait1 = w.object<trait1>(); // OK

请注意,我是在通过首先向下转换为派生类型,然后“向上转换”回特征来准确地说明如何进行转换。

关于reinterpret_cast

如果要从类转换为基类(从MyTypetrait1 ),则dynamic_cast将返回派生对象中基类子对象的指针或引用static_cast也可以正确进行此转换)。 这意味着返回的指针的值实际上可能与提供的指针的值不同。 reinterpret_cast将永远不会对指针值进行此类更改。 它只会将传递给它的任何内容重新解释为新类型,这显然是错误的。 显而易见的结论是不要在类层次结构内使用reinterpret_cast进行强制类型转换。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM