其中存储了type_info对象

Where is type_info object stored?

本文关键字:info 对象 type 存储      更新时间:2023-10-16

我从">Inside The C++Object Model"中了解到,type_info对象通常存储在虚拟表的第一个槽中。然而,我迭代了虚拟表中的成员:

class Base {
public:
    virtual void f() { cout << "Base::f" << endl; }
    virtual void g() { cout << "Base::g" << endl; }
    virtual void h() { cout << "Base::h" << endl; }
};
typedef void(*Fun)(void);
Base b;
(Fun)*((int*)*(int*)(&b)+0); // Base::f()
(Fun)*((int*)*(int*)(&b)+1); // Base::g()
(Fun)*((int*)*(int*)(&b)+2); // Base::h()

正如您从最后三行中看到的,我根本找不到type_info。

没有交叉编译器的方法可以从对象的地址获取type_info。你也不会期望会有;获得CCD_ 2的方法是使用特定的C++关键字:CCD_。

#include <iostream>
#include <typeinfo>
using namespace std;
class Base {
    public:
        virtual void f() { cout << "Base::f" << endl; }
        virtual void g() { cout << "Base::g" << endl; }
        virtual void h() { cout << "Base::h" << endl; }
};
int main(void)
{
    typedef void(*Fun)(void);
    Fun pFun = NULL;
    Base b;
    pFun = (Fun)(*((long *)(*((long *)(&b))) + 0));
    pFun();//Base::f()
    pFun = (Fun)(*((long *)(*((long *)(&b))) + 1));
    pFun();//Base::g()
    pFun = (Fun)(*((long *)(*((long *)(&b))) + 2));
    pFun();//Base::h()
    type_info *base_type = (type_info *)(*((long *)(*((long *)(&b))) - 1));
    cout << "typeinfo is:" << base_type->name() << endl;
    cout << "the result of typeid(Base).name():" << typeid(Base).name() << endl;
    return 0;
}

输出为:

Base::f
Base::g
Base::h
typeinfo is:4Base
the result of typeid(Base).name():4Base

我使用GCC 4.9.2,我的系统是64位的。所以我使用CCD_ 4而不是CCD_。

typeinfo对象通常存储在虚拟机的第一个插槽中桌子

我认为这是错误的
typeinfo对象通常存储在虚拟表之前
(long *)(*((long *)(&b))):这是虚拟表的地址
(long *)(*((long *)(&b))) - 1:这是type_info对象的地址
所以你可以看到base_type->name()的结果是4Base。结果与使用typeid相同。4Base中的4是你的类名(Base(中的字母数。更多信息请点击

此外:当你用-fdump-class-hierarchy编译代码时,你可以看到Vtable for Base

Vtable for Base
Base::_ZTV4Base: 5u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI4Base)
16    (int (*)(...))Base::f
24    (int (*)(...))Base::g
32    (int (*)(...))Base::h

您可以看到_ZTI4BaseBase::f之前
使用c++filt _ZTI4Base将输出typeinfo for Base

type_info只有在为某些编译器启用RTTI(运行时类型信息(编译标志时才可用。