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信息>代码>,也不希望有这样的用法;得到<代码> Type信息>代码>使用一个特定的C++关键字:<代码> Type ID > />代码> 类型yInformation只有在启用RTTI(运行时类型信息)时才可用。某些编译器的编译标志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
#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