返回   cpper编程论坛 > C/CPP/TMP/GP
注册账号 论坛帮助 会员列表 日历事件 搜索 今日新帖 标记版面已读

回复
 
LinkBack 主题工具 显示模式
  #1 (permalink)  
旧 2006-08-14
dayforever 的头像
初级会员
 
注册日期: 2006-07-07
帖子: 19
dayforever 正向着好的方向发展
发送 MSN 消息给 dayforever
默认 如何取得实例的数据偏移

基类Base有虚函数,那么产生了vtable
那么派生类的实例如何去的数据区的起始位置

class Base
{
public:
Base(){}
virtual ~Base(){}
virtual void VFunc(){}
int k;
};

class Test : public Base
{
virtual void VFunc(){}

int t;
};

那么
Test test;
&test取得的地址为包含vtable的地址,数据出错,从哪个偏移开始才是数据区(基类数据和派生类数据)

问题补充:
或者说如何计算每个类的虚表大小,以及数据部分的排布
多重继承的情况下,数据分布是否带有先后顺序了
察看对应asm,发现简单继承的话,基类和派生类共用一个4字节的vtable区,基类数据和派生类数据在vtable后面连续存放
多重继承的话,会有其他操作,但是没找到准确说明这个问题的iso标准出处,所以问问



数据区排列:

Test Base
------- -----
|Test的vtable| |Base的vtable|
|Base的数据| |Base的数据|
|Test的数据|

可是在多重继承的时候好像是这样排布的,非常不解
Test Base Base2
------- ----- -----
|Test的vtable| |Base的vtable| |Base2的vtable|
|Base的数据| |Base的数据| |Base2的数据|
|Base2的vtable|
|Base2的数据|
|Test的数据|





然后自己动手实验
试验关于多重继承
实验环境:vc2005

class Base
{
public:
Base():k1(0)
{
}
virtual ~Base()
{
}

virtual void Func()
{
}

char k1;
};

class BaseB
{
public:
BaseB():t(0)
{
}
virtual ~BaseB()
{
}

char t;
};

class Test : public Base , public BaseB
{
public:
Test():d1(0)
{
}
~Test(){}

virtual void Func(){}
char d1;
};

Test test;
char* a = (char*)&test;
char* b = (char*)&(test.d1);
char* c = (char*)&(test.k1);
char* d = (char*)&(test.t);

a 0x0012ff50
b 0x0012ff60
c 0x0012ff54
d 0x0012ff5c

在看
实际上的顺序是Base,BaseB,Test
Base的数据与a的距离是4个字节,这4个字节应该是vtable
BaseB的数据与a的距离是12个字节,和Base的数据开始位置,相差8个字节,这里放了什么?不知道(如果数据以4字节对齐,那么就多了4个字节的BaseB的vtable,所以这两个积类的vtable就不是放在一起的)
Test的数据与a的距离时16个字节,按照上面的说法,不足4字节的,按4字节对齐,那么就对了

iso看不懂,也没找到具体说明这个的地方
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #2 (permalink)  
旧 2006-08-14
普通会员
 
注册日期: 2006-03-08
帖子: 31
Juvexp 正向着好的方向发展
默认

关于数据如何排列没有具体的标准,看编译器如何实现了。
你可以看一下Inside the c++ object model的data semantics那一章,里面有很详细的讨论。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #3 (permalink)  
旧 2006-08-15
cat cat 当前离线
高级会员
 
注册日期: 2003-11-06
帖子: 1,563
文章: 6
cat 正向着好的方向发展
默认

多重继承不清楚,因为可能指针会被调整……

简单情况的话,这个估计就够了:

#define offsetof(type, member) ((char *)(&static_cast<type*>(0x1000000)->member) - (char *)(static_cast<type *>(0x10000000))

这个用来看子类和基类的偏移
#define offsetofclass(base, derived) ((char *)(static_cast<base*>((derived*)0x1000000))-(char *)0x1000000)

大概这个意思 上面的code没有测试 如有问题自己修正

大致如下用法:&test + offsetof(Test, t)
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #4 (permalink)  
旧 2006-08-16
普通会员
 
注册日期: 2006-03-08
帖子: 31
Juvexp 正向着好的方向发展
默认

引用:
作者: cat
多重继承不清楚,因为可能指针会被调整……

简单情况的话,这个估计就够了:

#define offsetof(type, member) ((char *)(&static_cast<type*>(0x1000000)->member) - (char *)(static_cast<type *>(0x10000000))

这个用来看子类和基类的偏移
#define offsetofclass(base, derived) ((char *)(static_cast<base*>((derived*)0x1000000))-(char *)0x1000000)

大概这个意思 上面的code没有测试 如有问题自己修正

大致如下用法:&test + offsetof(Test, t)
VC下直接用 (&Test::t) 就可以了,不过要求t是Test的non static public member
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #5 (permalink)  
旧 2006-08-16
高级会员
 
注册日期: 2002-09-16
帖子: 1,087
文章: 1
SpitFire 正向着好的方向发展
默认

引用:
VC下直接用 (&Test::t) 就可以了,不过要求t是Test的non static public member
这个是c++标准语法
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #6 (permalink)  
旧 2006-08-16
普通会员
 
注册日期: 2006-03-08
帖子: 31
Juvexp 正向着好的方向发展
默认

引用:
作者: SpitFire
这个是c++标准语法
但是书上说不同的编译器得到的偏移地址可能不一样,有些编译器下要用 &Test::t - 1
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #7 (permalink)  
旧 2006-08-17
bankrock 的头像
高级会员
 
注册日期: 2003-12-11
帖子: 847
文章: 7
bankrock 正向着好的方向发展
默认

这个看看Inside就可以了吧,编译器相关的,没有标准的。就算知道了也没什么大用处
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
回复

书签

主题工具
显示模式

发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛启用 表情符号
论坛启用 [IMG] 代码
论坛禁用 HTML 代码
Trackbacks are 启用
Pingbacks are 启用
Refbacks are 启用



所有时间均为格林尼治时间 +9。现在的时间是 08:14 AM


Powered by vBulletin® 版本 3.7.0
版权所有 ©2000 - 2009,Jelsoft Enterprises Ltd.
(C) Copy Right All Right Reserved 2001 - 2007

Search Engine Friendly URLs by vBSEO 3.1.0