用于验证类型的动态转换

Dynamic cast used for validating type

为了避免 X Y 情况,我正在尝试验证 void* 指针转换是否有效。

为了解决这个问题,我想使用 dynamic_cast 的属性。

给定以下代码:

class A
{
  virtual void foo(){}
};
class B
{
  virtual void bar(){}
};

void* createA() { return new A();}
void* createB() { return new B();}

int main()
{
   A* ptr =reinterpret_cast<A*>(createA());
   A* ptr2 = reinterpret_cast<A*> (createB());

   ptr = dynamic_cast<A*>(ptr); // not NULL as expected
   ptr2 = dynamic_cast<A*> (ptr2); // was expecting NULL, however it's a valid pointer
}

如果 RTTI 不是预期的类型,dynamic_cast 不应该以 NULL 失败吗?

通常解决此类问题的方法是给AB一个公共标签库class/interface。 void* 不保留任何类型信息。 reinterpret_cast<> 也会简单地覆盖任何可能存在的类型信息。

你可以这样做:

class Base {
public:
    virtual ~Base() {}
};
class A : public Base
{
  virtual void foo(){}
};
class B : public Base
{
  virtual void bar(){}
};

Base* createA() { return new A();}
Base* createB() { return new B();}

int main()
{
   Base* ptr = createA();
   Base* ptr2 = createB();

   ptr = dynamic_cast<A*>(ptr); // not NULL as expected
   ptr2 = dynamic_cast<A*> (ptr2); // NULL pointer now
}

dynamic_cast 不能用于检查指向任意内存地址的指针是否指向特定类型的对象。 dynamic_cast 将仅在该对象的类型可能位于要转换为的类型的继承链中的情况下,通过检查所指向对象的 RTTI 来执行转换。在您的示例中,将 B * 转换为 A * 将始终产生 nullptr,即使 B * 实际上指向 A:

A * a_ptr = dynamic_cast<A*>(reinterpret_cast< B* >(createA()));
assert(nullptr == a_ptr);

此外,您正在尝试将 A * 转换为 A *,这基本上会导致 noop:

5.2.7 Dynamic cast [expr.dynamic.cast]

3 If the type of v is the same as T , or it is the same as T except that the class object type in T is more cv-qualified than the class object type in v, the result is v (converted if necessary).