CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

类指针的强制转化问题?

楼主tidyduck(辨不清东南西北)2005-10-17 17:10:14 在 C/C++ / C++ 语言 提问

今天看到有这样的写法(CMainFrame*)m_pMainWnd,这样写的目的是不是为了调用派生类成员函数啊?  
  自己写了一个程序试了一下,是可以的。  
  可是有一点不明白:基类在创建对象之后,分配的内存不就固定下来了么?为什么指向该内存空间的“派生类指针”能够调用其派生函数呢?难道这内存内存自动增长了?  
  高手帮忙解答一下啊,谢谢!~  
   
  下面是自己写的试验程序:  
  #include   <iostream>  
  using   namespace   std;  
   
  class   BaseClass  
  {  
  public:  
  BaseClass();  
  OutPutBase();  
   
  protected:  
   
  private:  
  int   a;  
   
  };  
   
  class   GenClass:public   BaseClass  
  {  
  public:  
  GenClass();  
  OutPutGen();  
   
  protected:  
   
  private:  
  int   b;  
  };  
   
  BaseClass   *bCls=new   BaseClass;  
   
  GenClass   *pg1=(GenClass*)bCls;  
   
  void   main()  
  {  
  pg1->OutPutGen();  
  }  
   
  BaseClass::BaseClass()  
  {  
  cout<<"Base   Class!   "<<endl;  
  }  
   
  GenClass::GenClass()  
  {  
  b=1;  
  cout<<"Gen   Class!   "<<endl;  
  }  
   
  BaseClass::OutPutBase()  
  {  
  a=0;  
  cout<<a<<endl;  
  }  
   
  GenClass::OutPutGen()  
  {  
  b=1;  
  cout<<b<<endl;  
  }  
  问题点数:20、回复次数:13Top

1 楼qhfu(改个名字)回复于 2005-10-17 17:16:48 得分 0

调用虚函数时,   主要是跟编译期的邦定有关系,(CMainFrame*)m_pMainWnd     这样就会从   CMainFrame类的vptr表中查找,如果   CMainFrame类中没有   那个函数就会编译出错,,   而运行时,是跟实际指向的类型邦定,也就是派生类邦定。。上面说的是虚函数调用,,  
  如果不是虚函数的话,那么调用时就是编译期绑定。  
  指针类型的内存大小都是一样的,   4个字节Top

2 楼bm1408(向va_list学习~不用VC好多年~)回复于 2005-10-17 17:18:44 得分 2

vtable的伤用了~~Top

3 楼tidyduck(辨不清东南西北)回复于 2005-10-17 17:34:21 得分 0

回复人:   qhfu(崩溃)   (   )   信誉:105    
  =================================  
  您的意思是在编译的时候就指定分配派生类那么多的内存吗?  
   
  Top

4 楼fly_qj(青蛙王子)回复于 2005-10-17 18:39:05 得分 3

那C++的多态体现在哪去了?  
  你的问题正是多态的具体体现呗。Top

5 楼tidyduck(辨不清东南西北)回复于 2005-10-17 20:52:56 得分 0

刚刚又看了一下,发现用派生类指针指向基类的对象时,指向的对象长度发成了增长。  
  我想知道内存空间是如何变化的呢?如果该对象在内存中增长,那这个对象后面的内存为什么不会被覆盖呢?Top

6 楼qhfu(改个名字)回复于 2005-10-17 23:34:43 得分 0

内存是运行期分配的,如:  
   
  Base   *   b   =   new   Derived;  
  b通过new得到的内存大小是由 new后面这个派生类型决定的,,而不是由b的指针类型决定的。Top

7 楼tidyduck(辨不清东南西北)回复于 2005-10-17 23:42:58 得分 0

可是在用派生类指针之前和之后的对象长度不一样啊?  
   
  #include   <iostream>  
  using   namespace   std;  
   
  class   BaseClass  
  {  
  public:  
  BaseClass();  
  OutPutBase();  
   
  protected:  
   
  private:  
  int   a,aa;  
   
  };  
   
  class   GenClass:public   BaseClass  
  {  
  public:  
  GenClass();  
  OutPutGen();  
   
  protected:  
   
  private:  
  int   b;  
  };  
   
  BaseClass   bCls;//基类对象  
   
  GenClass   *pg1=(GenClass*)&bCls;//指向该对象的是一派生类指针  
   
  void   main()  
  {  
  cout<<sizeof(bCls)<<endl;    
  cout<<sizeof(*pg1)<<endl;   //两个结果并不一样  
   
  }  
   
  BaseClass::BaseClass()  
  {  
  cout<<"Base   Class!   "<<endl;  
  }  
   
  GenClass::GenClass()  
  {  
  b=1;  
  cout<<"Gen   Class!   "<<endl;  
  }  
   
  BaseClass::OutPutBase()  
  {  
  a=0;  
  cout<<a<<endl;  
  cout<<sizeof(this)<<endl;  
  }  
   
  GenClass::OutPutGen()  
  {  
  b=1;  
  cout<<b<<endl;  
  cout<<sizeof(this)<<endl;  
  }  
  Top

8 楼qhfu(改个名字)回复于 2005-10-18 00:02:54 得分 0

BaseClass   bCls;//基类对象  
   
  GenClass   *pg1=(GenClass*)&bCls;//指向该对象的是一派生类指针  
  (1)让派生类的指针指向基类的对象是一种错误的做法。  
  (2)这里并不存在多态, 只是把一个类型的指针强制转化成另外一个类型的指针解释。  
   
  (3)OutPutBase(); 这个函数没有返回类型竟然也行。   
  (4)cout<<sizeof(*pg1)<<endl; pg1的类型是GenClass编译期决定的,所以sizeof(*pg1)只是sizeof(Genclass);Top

9 楼tidyduck(辨不清东南西北)回复于 2005-10-18 09:46:09 得分 0

回复人:   qhfu(崩溃)   (   )   信誉:105     2005-10-18   00:02:00     得分:   0      
     
  BaseClass   bCls;//基类对象  
   
  GenClass   *pg1=(GenClass*)&bCls;//指向该对象的是一派生类指针  
  (1)这只是个测试程序,原程序的用法是  
  HMENU   hMenu   =   ((CMainFrame*)   m_pMainWnd)->NewMenu();  
  这个程序是一个图标菜单的例子,我觉得他是为了调用派生类的函数才这样做的,我的测试程序也通过了啊。  
  (2)同意,我也觉得不存在多态问题。  
  (3)为什么一定要有返回值呢?  
  (4)刚刚看了你的解释:  
  Base   *   b   =   new   Derived;  
  b通过new得到的内存大小是由 new后面这个派生类型决定的,,而不是由b的指针类型决定的。  
  可是由派生类指针指向基类对象所在的内存区域之后,再sizeof该指针对象发现其长度增加,这看上去是理所当然的,派生类嘛,自然要比基类的长度大了。问题是增加的这部分内存为什么不会覆盖原基类所占用内存的后面的部分呢?Top

10 楼qhfu(改个名字)回复于 2005-10-18 11:53:19 得分 5

(1)这只是个测试程序,原程序的用法是  
  HMENU   hMenu   =   ((CMainFrame*)   m_pMainWnd)->NewMenu();  
   
  这是一个派生类指针转化为基类指针。  
  (3)为什么一定要有返回值呢?  
  除了构造函数和构析函数,   还有什么函数能没有返回值,至少也要返回一个void   有的编译器好像默认返回void   所以能通过,但是这决定不是正确的编程方法,  
  (4)内存是不会在运行期无故增加,除了用new,,用强制解释只能暴力的把内存解释成不同的东西.  
  (5)越描越黑了, 建议你先把c++基础知识学扎实点 呵呵Top

11 楼tidyduck(辨不清东南西北)回复于 2005-10-18 14:54:29 得分 0

(1)HMENU   hMenu   =   ((CMainFrame*)   m_pMainWnd)->NewMenu();  
  有关于m_pMainWnd的定义如下:  
  CWnd*   m_pMainWnd;               //   main   window   (usually   same   AfxGetApp()->m_pMainWnd)  
  而有关CMainFrame的定义如下:  
  class   CMainFrame   :   public   CFrameWnd  
  {...}  
  难道m_pMainWnd是“派生类”指针,被转化成CMainFrame这个“基类”基类了?  
  我虽然C++学得一般,但谁是基类谁是派生还是能分清楚的!  
  (2)有关于是否有多态的问题,我问过几个网友,目前说法还不统一。  
  (3)无返回值的函数是C的用法,而C++对C是兼容的,在一些小程序上,我觉得完全可以使用。  
  (4)您是否运行过了我的程序呢?请问指针对象的长度增加如何解释?Top

12 楼yanjun_1982(山泉农夫)回复于 2005-10-18 15:35:11 得分 10

sizeof是编译时候使用的,它关心的不是指针指向的对象是什么类型,而是指针本身是什么类型.  
  至于你能使用基类指针来访问派生类的的函数,如果这个函数不涉及派生类的成员变量的话,  
  是没什么问题.因为对象内存中不存放成员函数的地址.  
  如果涉及到了派生类的成员变量,程序就不会按你想象中运行,  
  因为基类里并没有派生类的成员变量,基类对象内存空间没有被扩大.  
  PS:有virtual就有多态.  
  PS:我没运行过你的程序,也没留意看.Top

13 楼yanjun_1982(山泉农夫)回复于 2005-10-18 15:50:34 得分 0

嗯,其实你的想法也是有少少正确的.  
  基类指针能够访问到派生类的成员,这个派生类的成员的地址是放在基类对象内存空间之外的,  
  对这个成员变量进行访问是非法的,  
  在运行时会出错:对象周边空间被腐蚀(Stack   around   the   variable   "base_obj"   was   corrupt)Top

相关问题

  • 如何强制转化一个指针类型,当指针加1的时候地址加3
  • 一个托管的类指针对象,能转化成void*吗?
  • 怎么把DWORD转化为一个对话框类型的指针?
  • 请教:我在某个函数中为某个派生类分配了内存,现在要在另一个函数中删除它,但该函数只能得到指向父类的指针。如果我将父类的指针强制转化为该派生类的指针,然后delete会不会造成内存泄漏?如果会有什么解决办法么?
  • 强制类型转换于指针的问题
  • 关于指针类型强制转换的问题
  • 指针的强制转换
  • CString 类定义的字符串如何转化为char 型指针(急!在线等候)
  • 强制转换类型实现父类指针访问子类同名函数
  • 急切知道答案:强制转换指针类型的问题!!!

关键词

  • c++
  • 指针
  • 函数
  • 内存
  • 转化
  • genclass
  • 基类
  • baseclass
  • 派生类
  • pmainwnd

得分解答快速导航

  • 帖主:tidyduck
  • bm1408
  • fly_qj
  • qhfu
  • yanjun_1982

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo