如何在没有虚方法的情况下dynamic_cast一个类的指针?

时间:2018-06-07 05:46:43

标签: c++ oop llvm

我正在使用llvm库,我想检查llvm :: Value *是否实际上是llvm :: LoadInst *(llvm :: LoadInst继承自llvm :: Value)。

但遗憾的是,llvm :: Value并不包含任何虚拟方法! (是的,即使没有虚析构函数)是否可以在没有虚方法的类上使用dynamic_cast,还是有其他方法可以进行类型检查?

2 个答案:

答案 0 :(得分:3)

在LLVM中,有一个llvm::dyn_cast<T>将使用LLVM的内部构造从一种类型动态转换为另一种类型,只要它们确实是有效的转换 - 如果你使用了错误的类型T,它将返回nullptr

类似于:

llvm::Value *v = ... some code here ... 
...
llvm::LoadInst* li = llvm::dyn_cast<llvm::LoadInst>(v);
if (!li) { ... not a LoadInst, do whatever you should do here ... }
else { ... use li ... }

当然,如果您已经知道vLoadInst,那么您无需检查 - 但如果您遇到错误,assert(li && "Expected a LoadInst");会抓住。

请注意,{C }+标准T*不会llvm::dyn_cast<T>使用dynamic_cast

llvm::Value代码中的这条评论解释说,由于这个原因,没有完整的vtable(http://www.llvm.org/doxygen/Value_8h_source.html#l00207

   /// Value's destructor should be virtual by design, but that would require
   /// that Value and all of its subclasses have a vtable that effectively
   /// duplicates the information in the value ID. As a size optimization, the
   /// destructor has been protected, and the caller should manually call
   /// deleteValue.
   ~Value(); // Use deleteValue() to delete a generic Value.

答案 1 :(得分:1)

  

是否可以在没有虚拟方法的类上使用dynamic_cast

如果输入不是指针或对多态类型的引用,则无法使用dynamic_cast,即没有任何virtual成员函数。

  

还是有其他方法可以进行类型检查吗?

我想不到任何。您最好的选择是使用static_cast但是您必须非常确定您要投射的类型是有效的。

struct Base { ... };
struct Derived1 : Base { ... };
struct Derived2 : Base { ... };

void foo(Base* base)
{
    Derived1* ptr = static_cast<Derived1*>(base);
    // Use ptr
}

void bar()
{
    foo(new Derived1()); // OK.
    foo(new Derived2()); // Not OK since foo assumes that the pointer 
                         // really points to a Derived1 object.
}