C++指针漂移问题解决方法

  C++编程语言虽然功能强大,应用方式灵活,但是在实际编程中同样会出现各种各样的错误。在这里我们将会为大家详细介绍一下有关C++指针漂移的解决方法,希望本文介绍的内容可以帮助大家解决问题。

  最近我们在工作中碰到一个奇怪的问题,最后确定是多继承引起的C++指针漂移,跟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 v; //implicit type conversion v.insert(v.begin(), pab); void *pv = v[0]; pa = (A*)pv; 以下程序使用Cygwin/g++b编译通过:

  #include #include 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->b = 2; pab->a = 3; A* pa = (A*)pab; B* pb = (B*)pab; printf( "AB: %pn" " A: %pn" " B: %pn", pab, pa, pb); std::vector v; //implicit type conversion v.insert(v.begin(), pab); void *pv = v[0]; pa = (A*)pv; printf("pv is %pnpa is %pnpab %s pvn", pv, pa, (pab == pv) ? "==" : "!="); printf("A.a is %dn", pa->a); //forced type conversion pv = (void*)pab; pa = (A*)pv; printf("Now A.a is %dn", pa->a); } 运行结果:

  AB: 0x6b01f0 A: 0x6b01f4 B: 0x6b01f0 pv is 0x6b01f4 pa is 0x6b01f4 pab != pv A.a is 3 Now A.a is 2

时间: 2024-12-26 16:55:16

C++指针漂移问题解决方法的相关文章

C++指针漂移问题解决方案

C++编程语言虽然功能强大,应用方式灵活,但是在实际编程中同样会出现各种各样的错误.在这里我们将会为大家详细介绍一下有关C++指针漂移的解决方法,希望本文介绍的内容可以帮助大家解决问题. 最近我们在工作中碰到一个奇怪的问题,最后确定是多继承引起的C++指针漂移,跟C++对象模型有关.示意如下: class A {...}; class B{...}; class AB : public B, public A {...} ... AB *pab = new AB(); A* pa = (A*)p

php猴子选大王问题解决方法

  本文实例讲述了php猴子选大王问题解决方法.分享给大家供大家参考.具体分析如下: 问题描述: 一群猴子排成一圈,按1,2,...,n依次编号.然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去...,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫做大王.要求编程模拟此过程,输入m.n, 输出最后那个大王的编号. 解决方法: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

XHTML下JS浮动代码失效问题解决方法

XHTML下JS浮动代码失效问题解决方法 漂浮广告/对联代码 为什么在XHTML语言的网页中不能使用? 对联代码,查阅它在xhtml下的表达方式,结果很简单了.这是因为,按照标准来说,我们看到的窗体的滚动条不应该是 body 的,而是 HTML 的(也就是 document.documentElement 对象)所以,解决办法是:把html下不标准的代码"document.body.scrollTop"变换为"document.documentElement.scrollTo

MySQL5.0中文问题及JDBC数据库连接和JSP汉字编码问题解决方法总结

js|mysql|编码|汉字|解决|数据|数据库|数据库连接|问题|中文 解决这类问题的方法很多,今天在此简单的终结一下,把常碰到的问题解决方法记下来! 1,   MySQL5.0中文问题解决方案如下:     1.在dos环境下,用mysql --default-character-set=gbk -u root -p 这句话进入mysql~~     2.建数据库.表,如下:         create database admin;         use admin;        

ASP 插入数据, 换行问题解决方法

插入|解决|数据|问题 作用:当插入数据时, 把每行的回车符替换为 <br /> 方法, 只使用简单的 replace 方法-- content_ = replace(request.Form("content"),chr(13),"<br/>") 如使用函数, 可这样使用-- content_ = funcName(request.Form("content")) 文件: insertform.asp--插入数据表单页,

asp.net2.0开发遇到的小问题解决方法

asp.net|解决|问题 asp.net2.0开发遇到的小问题解决方法一.页面比较长,如果页面提交到服务器时保存滚动条的位置,可以使用下面的两种方式:1.Page.MaintainScrollPositionOnPostback当网页回发到服务器时,用户将返回到该页的页首.在较长的网页中,这意味着用户必须将页滚动到该页的上一位置.当 MaintainScrollPositionOnPostback 属性设置为 true 时,用户将返回到该页的上一位置.2. Page.SmartNavigati

jsp 中 ActionForm中文乱码问题解决方法

  jsp教程 中 actionform中文乱码问题解决方法 先我们来了解一下actionform actionform概念 actionform用于封装用户的请求参数,而请求参数是通过jsp页面的表单域传递过来的.因此应 保证actionform的参数,与表单域的名字相同. 编辑本段actionform配置 所有的actionform都被配置在struts-config.xm l文件中,该文件包括了一个form-beans的元素, 该元素内定义了所有actionform,每个actionfor

Android加载图片内存溢出问题解决方法

  这篇文章主要介绍了Android加载图片内存溢出问题解决方法,本文讲解使用BitmapFactory.Options解决内存溢出问题,需要的朋友可以参考下 1. 在Android软件开发过程中,图片处理是经常遇到的. 在将图片转换成Bitmap的时候,由于图片的大小不一样,当遇到很大的图片的时候会出现超出内存的问题,为了解决这个问题Android API提供了BitmapFactory.Options这个类. 2. 由于Android对图片使用内存有限制,若是加载几兆的大图片便内存溢出.Bi

Android开发中遇到端口号占用问题解决方法

  这篇文章主要介绍了Android开发中遇到端口号占用问题解决方法,本文给出了一个简洁实用的方法来解决这个烦人的问题,需要的朋友可以参考下 Android开发的时候经常遇到端口号被占用的问题,经常使程序无法运行,很烦人.我总结了一个很好的方法,非常实用.方法如下: (1):方法1: 第一步:1:netstat -ano | findstr "5037" 第二步:2:TASKLIST | findstr "9292" (2):方法2: 首先进入目录下:E: 代码如下