C++ Internals: VC RTTI - typeid

来源:互联网 发布:中信淘宝v卡线上办理 编辑:程序博客网 时间:2024/05/16 04:44
返回目录

在研究过VC的RTTI的基本结构之后,我们先来看看最简单的typeid是怎么实现的。
在VC中,当你对多态类的指针ptr使用typeid(*ptr)之后,编译器会做两件事情:首先是将指针进行调整,使它指向当前类的vftable处(注意,类的vftable未必处在类的开始),然后再调用__RTtypeid,返回type_info对象。我们可以试验一下下面的代码。

template<typename T>
const type_info &GetTypeID(const T *obj)
{
    if (typeid(*obj)==*__RTtypeid(obj))
        return typeid(*obj);
    else
        throw new std::bad_typeid("...");
}

template<typename T>
const TypeDescriptor *__RTtypeid(const T *ptr)
{
    if (!ptr) throw new std::bad_typeid("Attempted a typeid of NULL pointer!");
    const _s_RTTICompleteObjectLocator *pCompleteLocator=GetCompleteObjectLocator(ptr);
    TypeDescriptor *pTypeDescriptor=pCompleteLocator->pTypeDescriptor;
    if (!pTypeDescriptor) {
        throw std::__non_rtti_object("Bad read pointer - no RTTI data!");
    }
    return pTypeDescriptor;
}

可以看到,typeid的实现很简单。
这是因为编译器会在类的vftable(包括它自己的和从基类继承的)的第一个函数指针前面插入一个指向_s_RTTICompleteObjectLocator结构的指针,这个结构中会存放该类的TypeDescriptor(上面的GetCompleteObjectLocator函数就是用来从vftable获得s_RTTICompleteObjectLocator结构的)。因此,即使你将派生类的指针赋给基类的指针,你仍然可以利用上面的算法得到派生类的类型。