简体   繁体   English

如何动态广播没有虚拟方法的类的指针?

[英]How to dynamic_cast a pointer of a class with no virtual method?

I'm using the llvm library and I want to check if an llvm::Value * is actually an llvm::LoadInst * (llvm::LoadInst is inherited from llvm::Value). 我正在使用llvm库,我想检查llvm :: Value *是否实际上是llvm :: LoadInst *(llvm :: LoadInst继承自llvm :: Value)。

But sadly, llvm::Value doesn't contain any virtual method! 但是可悲的是,llvm :: Value不包含任何虚拟方法! (Yes, even without virtual destructor) Is it possible to use dynamic_cast on a class without virtual methods, or is there any other way to do the type checking? (是的,甚至没有虚拟析构函数)是否可以在没有虚拟方法的类上使用dynamic_cast ,或者是否有其他方法可以进行类型检查?

In LLVM, there is a llvm::dyn_cast<T> that will use LLVM's internal constructs to dynamically cast from one type to another, as long as they are indeed valid casts - if you use the wrong type T , it will return a nullptr . 在LLVM中,有一个llvm::dyn_cast<T> ,它将使用LLVM的内部构造从一种类型动态转换为另一种类型,只要它们确实是有效的类型转换-如果使用错误的类型T ,它将返回nullptr

So something like: 所以像这样:

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 ... }

Naturally, if you already DO know that v is a LoadInst , you don't need to check - but an assert(li && "Expected a LoadInst"); 自然地,如果您已经知道vLoadInst ,则无需检查-而是需要使用assert(li && "Expected a LoadInst"); will catch if you ever got that wrong. 如果您错了,它将抓住。

Note that you don't use T* for llvm::dyn_cast<T> , as you would for the C+++ standard dynamic_cast . 请注意,对于llvm::dyn_cast<T> ,不要使用T* ,而对于C +++标准dynamic_cast llvm::dyn_cast<T>使用T*

This comment in the code for llvm::Value explains that there is no vtable exactly for this reason ( http://www.llvm.org/doxygen/Value_8h_source.html#l00207 ) 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.

Is it possible to use dynamic_cast on a class without virtual methods, 是否可以在没有虚拟方法的类上使用dynamic_cast

There is no way to use dynamic_cast if the input is not pointer or reference to a polymorphic type, ie does not have any virtual member functions. 如果输入不是指针或对多态类型的引用,即没有任何virtual成员函数,则无法使用dynamic_cast

or is there any other way to do the type checking? 还是有其他方法可以进行类型检查?

I can't think of any. 我想不到。 Your best option is to use static_cast but then you must be very certain that the type to which you are casting is valid. 最好的选择是使用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.
}

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

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