Phoenix@上海

Software Evolution

原创 C++里面多继承带来的指针漂移问题收藏

C++里面多继承带来的指针漂移问题

转载请注明出处:http://blog.csdn.net/phoenixsh

最近我们在工作中碰到一个奇怪的问题,最后确定是多继承引起的指针漂移,跟C++对象模型有关。示意如下:

class A {...};
class B{...}
;
class AB : public B, public A {...}

...
AB 
*pab = new AB();
A
* pa = (A*
)pab;
B
* pb = (B*)pab;

这时候你发现pa和pb的值是不一样的!它们中有一个跟pab是相等的,而另外一个产生了偏移。如果把AB的声明中A和B的顺序调换一下,则产生偏移的指针也会变为另外一个。

为了确定这是编译器做了转换的缘故,利用void指针愚弄编译器:

void *pv = (void*)pab;
pa 
= (A*)pv;

这时候pa的值倒是跟pab相等了,然而指向了错误的地方。从pab到pa的转换,依赖于路径的选择,让人不是很放心。还不知道把指针放入容器中再取出来,会不会出错。当然,上面使用了强制类型转换,在良好的程序中应该避免。如果只有隐式转换,可以得到正确的结果:

std::vector<A*> v;
//implicit type conversion

v.insert(v.begin(), pab);
void *pv = v[0
];
pa 
= (A*)pv;

以下程序使用Cygwin/g++b编译通过:

#include <stdio.h>
#include 
<vector>

class A 
{
public
:
 
int
 a;
}
;
class
 B 
{
public
:
 
int
 b;
}
;
class AB : public B, public
 A 
{
public
:
 
int
 ab;
}
;

int main(int argc, char **
argv)
{
 AB 
*pab = new
 AB();
 pab
->ab = 1
;
 pab
->= 2
;
 pab
->= 3
;

 A
* pa = (A*
)pab;
 B
* pb = (B*
)pab;

 printf( 
"AB: %p "
 
  
" A: %p "
 
  
" B: %p "
,
  pab, pa, pb);

 std::vector
<A*>
 v;
 
//implicit type conversion

 v.insert(v.begin(), pab);
 
void *pv = v[0
];
 pa 
= (A*
)pv;
 printf(
"pv is %p pa is %p pab %s pv ", pv, pa, (pab == pv) ? "==" : "!="
);

 printf(
"A.a is %d ", pa->
a);
 
//forced type conversion

 pv = (void*)pab;
 pa 
= (A*
)pv;
 printf(
"Now A.a is %d ", pa->
a);
}

发表于 @ 2006年07月16日 11:38:00|评论(loading...)

新一篇: 笔记:Vector IRAM Processor (0) | 

用户操作
[即时聊天] [发私信] [加为好友]
phoenixsh
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
phoenixsh的公告
所有文章除注明转载或者翻译之外,均为原创。转载请注明出处,谢谢!
文章分类
收藏
    技术新闻
    ACM Tech News
    网络杂志
    ACM Queue
    友情链接
    absurd
    eXcel
    存档
    Csdn Blog version 3.1a
    Copyright © phoenixsh