C++ Internals: VC RTTI - typeid

返回目录

在研究过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结构的)。因此,即使你将派生类的指针赋给基类的指针,你仍然可以利用上面的算法得到派生类的类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值