王朝网络
分享
 
 
 

关于data member pointer的一些讨论

王朝other·作者佚名  2006-01-22
宽屏版  字体: |||超大  

今天为了测试data member pointer,在BCB6里写了一段程序,却发现了一点问题。

代码很简单:

struct Base1 { int val1;};

printf("&Base1::val1 = %p, %d\n", &Base1::val1, 2);

结果发现数字2 输出失败,显示为0,察看CPU发现:

0040116B 6A02 push 0x02

0040116D FF35A8204000 push dword ptr [0x4020A8]

00401173 FF35A4204000 push dword ptr [0x4020A4]

00401179 68D4204000 push 0x004020d4

0040117E E831020000 call CC3260MT._printf

00401183 83C410 add esp,0x10

原来第一个参数“两次”被push入栈,导致printf认为第一次push的就是%d的参数。将上面的程序改为:

printf("&Base1::val1 = %p, %d %d\n", &Base1::val1, 2);

后可以发现2的输出。

为什么会将pointer入栈两次?

----------------------------------------------------

1/9/2006通过一个简单的测试:

int Base1::*pp;

printf("%d\n",sizeof(pp));

发现在BCB中是8字节(即使将Data Alignment设置成word或者double word也没有区别),而在VC或者GNU C++中是4字节。

谢谢某鸟的解释,于是查了一下__closure。让人惊讶的是他可以让一个“普通”的函数指针指向“thiscall”调用的成员函数(Using a closure, you can get a pointer to member function for an object (i.e. a particular instance of a class). The object can be any object, regardless of its inheritance hierarchy. The object抯 this pointer is automatically used when calling the member function through the closure. )。看来多出来的4字节是用来记录this指针了。(结果也很好证实)

不过:

[问题一]:

为什么data member pointer也会多这4字节?用来做什么?还是只是单纯的为了统一?

试了几个case,包括虚拟继承,发现“后面”的4字节都是0。本来以为是记录继承类中基类的偏移量,发现不是。又以为和上面一样与this指针有关系,不过,data member pointer用this指针做什么?后来猜想为了决议二义性,但因为下面的问题,测试未遂。

[问题二]:

本来想做另外一个实验:

struct Base1 { int val1; };

struct Base2: Base1 { int val2;};

struct Base3: Base1 { int val3;};

struct Derived : Base2, Base3 {int val4;};

如果定义一个Derived d; 显然可以通过d.Base2::val1和d.Base3::val1来分别访问两个val1,但如果是data member pointer呢?如何解决二义性,用一个int Base1::*pp;如何分别访问两个val1?

我试了

pp = &Derived::Base2::val1;

pp = &Derived::Base2.val1;

pp = &Derived.Base2::val1;

pp = &Derived.Base2.val1;

都不行。

----------------------------------------------------

1/13/2005

本来只想把问题局限到BCB中,不过既然不停的提到了VC中data member pointer。我也说说自己的看法。

一如ICOM(《Incide The C++ Object Model》,《深入探索C++对象模型》)中说,一般data member pointer用offset+1,这样可以避免以下的混乱。

int Base1::*p1 = 0;

int Base1::*p2 = &Base1::val1;

但是在VC中直接用的是offset。VC中避免这种的混乱的方法是int Base1::*p1 = 0;这样语句,实际上把p1置成了0xFFFFFFFFH,而非像普通pointer一样的0。判断

if (p1 == 0)

被转换成为 cmp dword ptr[...], 0FFFFFFFFh

相当于说,BCB/GNU data member pointer的值 = VC data member pointer的值 + 1

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有