随笔 - 31  文章 - 128  trackbacks - 0
<2006年10月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

留言簿(5)

随笔分类(38)

随笔档案(31)

收藏夹(4)

College

High School

最新随笔

搜索

  •  

积分与排名

  • 积分 - 54989
  • 排名 - 411

最新评论

  • 1. re: [yc]详解link
  • 面试的时候面试官就问过我什么是编译和链接,我说编译就是把代码文件生成目标文件,链接就是把目标文件生成可执行文件,他说不对,又问我什么是动态链接,还问我预编译都做什么处理。。。都在这里找到了答案!!!!
  • --王至乾
  • 2. re: [yc]详解link
  • @刘伟
    我是说博主,不是叫你啊
  • --溪流
  • 3. re: [yc]详解link
  • 谁是石老师,我不是哈@溪流
  • --刘伟
  • 4. re: [yc]详解link
  • 石老师?我是溪流~
  • --溪流
  • 5. re: [yc]详解link
  • 期待楼主下文啊,多谢楼主了
  • --刘伟

阅读排行榜

评论排行榜

    近日在学校bbs上与人讨论C++的typeid关键字的实现问题,有人提到type_info的地址是存放在虚表的第一个位置上,颇觉得不妥,于是我在vc2003下实验了一番

    在vc下,使用typeid的时候,如果typeid施加给的类型是没有vptr的class或者根本不是class
那么汇编是
mov  dword ptr [addr],offset A `RTTI Type Descriptor' (42AD40h)
也就是编译器生成一个简单的type_info对象的表,并且在编译期静态决定下标,做一个简单查表操作。

如果typeid的操作对象是具有vptr的class,但是并不是一个引用或者指针的解引用形式,例如

A a;
typeid(a);


那么仍然仅仅会做查表操作


如果typeid的操作对象是具有vptr的class,并且是引用或者指针的解引用形式,例如

* =   new  A;
A
&  r  =   * p;
typeid(
* p);
typeid(r);


那么就会调用一个叫___RTtypeid的函数,并通过某种方法来获取type_info对象
下面是___RTtypeid的反汇编,这里只列出关键的几条指令

0041213E  mov         ecx,dword ptr [inptr]    ;inptr是对象的地址
00412141   mov         edx,dword ptr [ecx] 
00412143   mov         eax,dword ptr [edx - 4
0041215F  mov         ecx,dword ptr [eax
+ 0Ch] 
00412162   mov         dword ptr [ebp - 48h],ecx 
0041216C  mov         eax,dword ptr [ebp
- 48h] 


基本上等价于C语言的

int  a1  =  ( int )p;  // p是对象的地址
int  a2  =   * ( int * )a1  -   4 ;
int  a3  =   * ( int * )a2  +   12 ;
int  a4  =   * ( int * )a3;

 

那么从这段代码可以看出vc下type_info对象的存放位置[如下图]



也就虚表下标为-1的位置上存放了一个指向一个未知的表的指针(暂且将此表命名为runtime_info_table)
runtime_info_table的第4格上存放了type_info对象的地址
至于runtime_info_table里前3格上存放的是什么, 还需要再研究研究
一般来说它们全是0, 但是对于多重虚继承的类, 第二格上会是4, 可能和指针的偏移量有关.

posted on 2006-10-26 10:46 shifan3 阅读(3330) 评论(5)  编辑 收藏 引用 所属分类: C++

FeedBack:
# re: VC下typeid实现及内存布局分析 2006-10-26 18:00 jj
我怎么测试的时候,带vtpr的类也是mov dword ptr [addr],offset A `RTTI Type Descriptor' (42AD40h)
  回复  更多评论
  
# re: VC下typeid实现及内存布局分析 2006-10-26 20:42 Francis Arcanum
首先要开rtti开关
然后必须这样测试才行
class A
{
public:
virtual void f(){}
};
class B : public A{};
A* p = new B;
A& r = *p;
typeid(*p);
typeid(r);
也就是能够调用___RTtypeid的东西必须是指针解引用或者引用
对象实体和其他类型由于实际类型在编译器就能固定,就直接查表了  回复  更多评论
  
# re: VC下typeid实现及内存布局分析 2006-12-09 22:47 euclid
验证了我的想法。  回复  更多评论
  
# re: [yc]VC下typeid实现及内存布局分析 2007-08-21 00:01 非非是是(||)
那typeid(1);呢
>int
  回复  更多评论
  
# re: [yc]VC下typeid实现及内存布局分析 2007-08-21 15:05 Francis Arcanum
@非非是是(||)
mov dword ptr [addr],offset A `RTTI Type Descriptor' (42AD40h)
直接查表  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理