type_info对象存储在哪里? 我从“C++对象模型内部”中看到,Type信息对象通常存储在虚拟表的第一个插槽中。但是,我迭代了虚拟表中的成员: 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() 类基{ 公众: 虚空格f~({couth

type_info对象存储在哪里? 我从“C++对象模型内部”中看到,Type信息对象通常存储在虚拟表的第一个插槽中。但是,我迭代了虚拟表中的成员: 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() 类基{ 公众: 虚空格f~({couth,c++,C++,)没有一个交叉编译的方法来从对象的地址获得 Type信息>代码>,也不希望有这样的用法;得到 Type信息>代码>使用一个特定的C++关键字: Type ID > />代码> 类型yInformation只有在启用RTTI(运行时类型信息)时才可用。某些编译器的编译标志 #include <iostream> #include <typeinfo> using namespace std; class Base { public: virtual

)没有一个交叉编译的方法来从对象的地址获得<代码> Type信息>代码>,也不希望有这样的用法;得到<代码> Type信息>代码>使用一个特定的C++关键字:<代码> Type ID > />代码> 类型yInformation只有在启用RTTI(运行时类型信息)时才可用。某些编译器的编译标志

#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;
}
我使用GCC4.9.2,我的系统是64位的。所以我使用
long
而不是
int

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

我认为这是错误的。
type_info对象通常存储在虚拟表之前。
(长*)(*((长*)(&b))
:这是虚拟表的地址
(长*)(*((长*)(&b))-1
:这是类型_信息对象的地址
因此,您可以看到
base\u type->name()
的结果是
4Base
。结果与使用
typeid
相同。
4Base
中的
4
是类名中的字母数(
base

此外: 将代码与
-fdump类层次结构
组合时,您可以看到基本的
Vtable

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
您可以看到
\u ZTI4Base
位于
Base::f


使用
c++filt\u ZTI4Base
将输出
typeinfo for Base

是什么阻碍编译器将其设置为-1?在访问type\u info时检查生成的汇编代码…有所有vtable/vtable表和type\u信息指针的描述副本。type\u信息实际上存储在任何地方吗?我认为大多数时候,compiler知道足够的信息,因此可以在编译时优化typeid(无论什么)。是的,
type\u info
被“存储在某处”。它是编译器必须为其创建存储的真实对象。但更可能的是,它存储在全局数据中,因为
type\u info
对象必须存在到执行结束。@Nicol是的,我也这么认为,因为您无法复制它们(
type\u info
s)但您可以返回对它们的引用,这表明它们独立存在于某个地方。请注意,不“启用”RTTI阻止您的编译器与标准保持一致。虽然许多编译器确实支持将RTTI转换为扩展,但该语言不支持。@Nicol Bolas:因此,仅出于测试目的,将类型_info的地址转换为vtable(大多数编译器都实现了它)你需要启用RTTI。我甚至不确定这是一个答案还是一个问题。我不知道如何(或者我是否应该)标记这个。好的,我删除了这个问题。
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