关于c++的虚函数表问题

支持英文数字 2012-06-26 08:30:16

#include <iostream>
using namespace std;
class A{
public:
virtual void g(){
cout << "A::g" << endl;
}
private:
virtual void f(){
cout << "A::f" << endl;
}
};

class B:public A{
void g(){
cout << "B::g" << endl;
}
virtual void h(){
cout << "B::h" << endl;
}
int a;
};

typedef void (*fun)(void);

int main(){
B b;
fun pfun;
for (int i = 0; i < 3; i++){
pfun = (fun)*((int*)*(int*)(&b)+i);
pfun();
}
return 0;
}


上面这段程序,程序运行结果是
B::g
A::f
B::h
我所不能理解的是,在深度理解c++对象模型中讲的是,虚表的第一个位置是类型信息,但是在这里,我却找不到类型信息,那么这个类型信息存放在哪里呢?
...全文
234 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2012-06-27
  • 打赏
  • 举报
回复
《深度探索C++对象模型》
Coder_Y_Jao 2012-06-27
  • 打赏
  • 举报
回复
更正个描述错误,+3不是那个指针的高地址处,是那个指针向高地址偏移3个,
至于为什么要偏移3个,我是在调试时在Memory中查看到那个地方存储的值恰好和直接用typeid取出来的值是一样的:
const type_info* ti = &typeid(b);
Coder_Y_Jao 2012-06-27
  • 打赏
  • 举报
回复
以上是在vs2008中得到的,其他编译器不保证也是这样存放的。
你自己调试时查看Memory中vptr地址前后存放的内容也可以找到的。估计其他编译器也大同小异
另外以上代码为修改楼主的代码片段,楼主自己补充完整吧,记得#include <typeinfo>
Coder_Y_Jao 2012-06-27
  • 打赏
  • 举报
回复
在vs2008中type_info的地址在虚函数表前面,刚刚测试并打印出来了,下面代码中
*(((int*)*(vptr-1))+3)也就是取前一个指针的高字节处

int main(){
B b;
fun pfun;
for (int i = 0; i < 3; i++){
pfun = (fun)*((int*)*(int*)(&b)+i);
pfun();
}


int* vptr = (int*)*(int*)(&b);
const type_info* ti = (const type_info*)*(((int*)*(vptr-1))+3);
std::cout << ti->name() << std::endl;

return 0;
}
Das_Herz 2012-06-27
  • 打赏
  • 举报
回复
不同编译器不一样的。
typeid
支持英文数字 2012-06-27
  • 打赏
  • 举报
回复
这个问题就是因为深度探索c++对象模型而产生的。[Quote=引用 14 楼 的回复:]

《深度探索C++对象模型》
[/Quote]
支持英文数字 2012-06-27
  • 打赏
  • 举报
回复
受教。[Quote=引用 12 楼 的回复:]

以上是在vs2008中得到的,其他编译器不保证也是这样存放的。
你自己调试时查看Memory中vptr地址前后存放的内容也可以找到的。估计其他编译器也大同小异
另外以上代码为修改楼主的代码片段,楼主自己补充完整吧,记得#include <typeinfo>
[/Quote]
支持英文数字 2012-06-26
  • 打赏
  • 举报
回复
那动态类型信息是怎么获得的呢?[Quote=引用 7 楼 的回复:]

学习C++时,就没听说类的vtble里还有类型信息
[/Quote]
支持英文数字 2012-06-26
  • 打赏
  • 举报
回复
那这个类型信息是怎么获得的呢?[Quote=引用 7 楼 的回复:]

学习C++时,就没听说类的vtble里还有类型信息
[/Quote]
feiyue12061 2012-06-26
  • 打赏
  • 举报
回复
学习C++时,就没听说类的vtble里还有类型信息
W170532934 2012-06-26
  • 打赏
  • 举报
回复
这个不要抓住书本不放啦。那本书的C++编译器是很老的。和现在的编译器不一样了。
但是编译器厂商都会将类型信息写到虚表中,但是在程序中,我没看到啊,第0个位置就直接是第一个虚函数了。。。
但是你的确没有看到啊。
W170532934 2012-06-26
  • 打赏
  • 举报
回复
这个不要抓住书本不放啦。那本书的C++编译器是很老的。和现在的编译器不一样了。
但是编译器厂商都会将类型信息写到虚表中,但是在程序中,我没看到啊,第0个位置就直接是第一个虚函数了。。。
但是你的确没有看到啊。
W170532934 2012-06-26
  • 打赏
  • 举报
回复
这个不要抓住书本不放啦。那本书的C++编译器是很老的。和现在的编译器不一样了。
但是编译器厂商都会将类型信息写到虚表中,但是在程序中,我没看到啊,第0个位置就直接是第一个虚函数了。。。
但是你的确没有看到啊。
wlnju 2012-06-26
  • 打赏
  • 举报
回复
这指针看的我泪流满面,我还是老老实实看书去了
支持英文数字 2012-06-26
  • 打赏
  • 举报
回复
我用的是g++4.4.5的编译器,虽然c++没要求说必须将类型信息写在虚表中,但是编译器厂商都会将类型信息写到虚表中,但是在程序中,我没看到啊,第0个位置就直接是第一个虚函数了。。。
[Quote=引用 1 楼 的回复:]

你用的是作者说的C++front编译器吗?
[/Quote]
hello_world000 2012-06-26
  • 打赏
  • 举报
回复
你用的是作者说的C++front编译器吗?

65,184

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧