CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  工具平台和程序库

关于data slicing一个问题,讨论下吧:)

楼主mmlymlymly(mly)2003-11-02 19:55:52 在 C/C++ / 工具平台和程序库 提问

#include   <iostream>  
  using   namespace   std;  
   
  class   A  
  {  
  public:  
  A(){cout<<"bbb"<<endl;}  
  A(const   A   &)   {cout<<"aaa"<<endl;}  
  virtual   void   prin(){cout<<"a"<<endl;}  
  ~A(){cout<<"end"<<endl;}  
  };  
  class   B:public   A  
  {  
  public:  
  B(){}  
  virtual   void   prin(){cout<<"b"<<endl;}  
  };  
  int   main()  
  {  
  B   a;  
  ((A)a).prin();  
  a.prin   ();  
  return   0;  
  }  
  运行结果是  
  bbb  
  aaa  
  a  
  end  
  b  
  end  
  请问为什么会产生一个调用缺省构造函数的A的对象,是语法分析的问题还是data   slicing产生的结果。  
   
  问题点数:100、回复次数:3Top

1 楼xueweizhong(薛卫忠)回复于 2003-11-02 20:45:11 得分 40

class   B:public   A  
  {  
  public:  
  B(){}  
                    ^^^^^  
   
  等价于   B()   :   A()   {}  
   
  导致   B   a;  
  构造A基类子对象时导致A::A()被调用,  
  所以程序一开始就打印了  
  bbbbTop

2 楼daizh()回复于 2003-11-02 20:50:32 得分 30

看完下面的解释你就明白了。  
   
  这实质是“类的构造函数调用顺序是什么?”  
   
  如果一个类有多个基类,基类的构造函数在继承类的构造函数之前被调用。基类的构造函数以被声明的顺序被调用。下面是一个例子:  
   
  class   Y   {...}    
  class   X   :   public   Y   {...}    
  X   one;    
   
  构造函数的调用顺序是下面的顺序:  
   
  Y();   //   基类的构造函数  
  X();   //   继承类的构造函数  
   
  对于多基类的情况,下面是一个例子:  
   
  class   X   :   public   Y,   public   Z    
  X   one;  
   
  构造函数以声明的次序调用。  
   
  Y();   //   基类构造函数首先被调用  
  Z();    
  X();    
   
  虚基类的构造函数在任何非虚基类构造函数前调用。如果构造中包括多个虚基类,它们的调用顺序以声明顺序为准。如果虚类是由非虚类派生而来,那非虚类的构造函数要先被调用。下面是一个例子:  
   
  class   X   :   public   Y,   virtual   public   Z    
  X   one;    
   
  调用顺序如下:  
   
  Z();   //   虚基类初始化  
  Y();   //   非虚基类  
  X();   //   继承类  
   
  下面是一个复杂的例子:  
   
  class   base;    
  class   base2;    
  class   level1   :   public   base2,   virtual   public   base;    
  class   level2   :   public   base2,   virtual   public   base;    
  class   toplevel   :   public   level1,   virtual   public   level2;    
  toplevel   view;  
   
  构造函数调用顺序如下:  
   
  base();   //   虚基类仅被构造一次  
  base2();    
  level2();   //   虚基类  
  base2();  
  level1();  
  toplevel();  
   
  如果类继承中包括多个虚基类的实例,基类只被初始化一次。  
  Top

3 楼magicblue(小飞侠)回复于 2003-11-02 21:20:31 得分 30

运行过程为:  
   
            B   a;  
   
  要构造a,首先要先构造B的基类A的部分,调用A的构造函数  
  输出   bbb  
   
            ((A)a).prin();  
   
  进行C风格的类型转换,把a从B类型转换到A类型,调用A的拷贝构造函数(参数为a,这个时候才是data   slicing,a的B类型信息部分被sliced)  
  输出   aaa  
  并生成一个临时变量,类型为A,并调用这个临时变量的prin(),  
  输出   a  
  第二句语句结束,临时变量自动被析构  
  输出  
  end  
   
            a.prin   ();  
   
  这个a是最先构造的,不是临时变量  
  输出   b  
   
  程序结束,a被析构  
  输出   end  
   
  这就是整个程序的执行过程Top

相关问题

  • 讨论一下::
  • 讨论一下
  • 讨论一下Session.
  • 讨论一下UpdateWindow().
  • 讨论一下 mpeg技术
  • 大家讨论一下window.close()
  • 讨论一下建模.
  • 欢迎讨论一下C#
  • 讨论一下Dev-C++
  • 共同讨论一下SOAP

关键词

得分解答快速导航

  • 帖主:mmlymlymly
  • xueweizhong
  • daizh
  • magicblue

相关链接

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

广告也精彩

反馈

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