欢迎光临112期刊网!
网站首页 > 论文范文 > 计算机论文 > 计算机应用 > 深度探索C++多重继承与虚拟继承在对象模型中的

深度探索C++多重继承与虚拟继承在对象模型中的

日期:2023-01-24 阅读量:0 所属栏目:计算机应用


摘 要:本文主要探索了在虚拟继承和简单多重继承情形下,类内的成员数据,成员函数,基类等在派生类中的结构。

关键词:虚拟继承;多重继承;层次结构;内存布局
  对于编写C++的程序员,一定多少使用过它语法中最基本也是最大的特点:继承与派生。那么一个类的产生会带来多大的空间开销,派生类和基类在数据、函数的内存结构上又有什么特点?
  让我们从最简单的开始,一步一步展开我们的继承探索之旅。  
一、空基类空成员虚拟继承

  我们看如下代码:
  
  
  class A{};
  class B:public virtual A{};
  class C:public virtual A{};
  class D:public B,public C{};
  
  
  
  图1-1 各个类层次结构
  

  可以明显的看到,上述各个类都是空类,所有语句只表达了继承关系而不具备任何数据处理功能,没有成员数据,没有成员函数。那么对他们使用Sizeof 的结果应该都是0。
  但是结果是这样的吗?
  结果如下:           
  为什么会出现这样的结果呢?
  其实空基类隐藏一个带有编号性质的1字节Char用与区分该类生成的不同实体:
   A a1,a2;
   if(&a1= =&a2) cout<<""the  same  address.""<   但class B与class C 为什么又是4字节呢?(其实很多编译器编译的结果是8 而D大小是12字节)
  事实上,这个测试具有三方面的影响共同造成:
  1. 为虚基类地址指针付出的代价  当语言支持虚拟继承就会增加负担。在派生类中,这个额外的负担是一个指针,他指向虚基类或是一个与地址相关的表格,表格中可能带有虚基类的地址或者一个虚基类与派生类的内存偏移量,作用就是找到他的虚基类。
  2.编译器对于派生类的优化  虚基类的1字节区分也会出现在B与C类中的尾部
  ent限制  以上B、C两类就应该各有了5字节,在大部分机器中,逻辑数据块会受到“对齐”限制,使他们按照整数大小对齐存取而填空,这里填充3字节(Alignment就是将数值调整到当前编译器整数字节的倍数以使存取通道获得最大效率)
             
  结果是8字节的空派生类,为什么某些编译器产生出4字节的空派生类?比如这次试验的结果呢,这是编译器对于派生类的优化措施,他的内存分布如下:
  
  编译器为了优化内存空间,将虚基类视作派生类的一个数据成员,是派生类开头的一部分,所以导致派生类并非空类型,而节约了1字节的空区分码和3字节的补齐。这就造成了空派生类只有4字节大小。
  同样的,对于D类而言,不同的优化策略造成两种不同的分布:
  
  编译器在众多不同的结构中产生多种分布结果,正说明了C++在对象模型中的进化过程,一个非优化系统被提出,为一般情况提供了解决方案,当特殊的模型和例子被提出,很多新的优化处理方式被引入编译器,最后导致一种新的标准诞生。比如C++中的虚函数列表也是一样的例子。
   这个实验中,如果给基类增加任何一个成员数据,那么编译器优化与非优化会产生相同的结果与对象布局。
  
  二.多重继承
  多重继承的模型相对来说就复杂一些,涉及到成员数据与成员函数,以及多个基类在派生类中分布的问题。
  下面这组类是描述物理中质点空间坐标与速度的类,当然,我们只抽象出我们需要的简单部分内容,其他的都忽略了。
  class Position2D  //平面位置矢量
  {  public: //省略若干virtual接口,有虚函数列表指针(vptr)
     Protected:
        Float x,y; };
  class Position3D:public Position2D  //位置矢量
  {  public: //省略若干virtual接口,有虚函数列表指针(vptr)
     Protected:
        Float z; };
  class Direction2D  //2D速度矢量
  {  public://省略若干virtual接口,有虚函数列表指针(vptr)
     Protected:
        Direction2D * direct;};
  class  Direction3D:public Position3D,Public Direction2D   //3D速度矢量
   {  public: //省略若干接口,有虚函数列表指针(vptr)
      protected:
        float derect_z;};
   对于这样一个类群,我们根据集成关系图来分析各个类的数据在内存中的分布(对象模型).
  
  
   按照内部数据成员存储在类中,虚函数以及成员函数存储在函数列表中的原则,大致可以看出其内存中的存储分布:
  
  
  这样的模型有什么作用呢?这主要是在解决数据向上向下转换时,告诉我们,非标准的操作什么样的能做,什么样的不能做,为什么不能这样做:
  
  Extern void change( const Direction2D &);
  Direction3D d;
  ..........
  //将一个Direction3D 转换为一个Direction2D对象,不自然,但仍然可以操作
  Change(d);
  而且支持调用一切Direction2D的函数。
  再比如:
  Direction3D d3d;
  Direction2D *p2d;
  Position2D *p2p;
  Position3D *p3p;
  那么 p2d=&d3d 这个操作需要内部转换。
  而 p2p=&d3d;  p3p=&d3d; 都只需要直接拷贝地址就可以完成(重合的内部结构,看图2.2)。
  这对于我们更好的编写程序,在指针中赋值带来了可调节的余地。 
  至此,对于虚拟继承与多重继承的各个类在内存中的结构,我们已经都有了大致的了解,这对于我们写程序时,能够利用最底层的特点,编写出富有效率的程序带来了实际的意义。限于篇幅的关系,这里就暂时不讨论多重继承与虚拟继承的混合模式及内联函数、友元等等内容了。  
  参考文献:
  《C++标准程序库》(德)Nicolai is著2002华中科技大学出版社 本文链接:http://www.qk112.com/lwfw/jsjlw/jisuanjiyingyong/241658.html

论文中心更多

发表指导
期刊知识
职称指导
论文百科
写作指导
论文指导
论文格式 论文题目 论文开题 参考文献 论文致谢 论文前言
教育论文
美术教育 小学教育 学前教育 高等教育 职业教育 体育教育 英语教育 数学教育 初等教育 音乐教育 幼儿园教育 中教教育 教育理论 教育管理 中等教育 教育教学 成人教育 艺术教育 影视教育 特殊教育 心理学教育 师范教育 语文教育 研究生论文 化学教育 图书馆论文 文教资料 其他教育
医学论文
医学护理 医学检验 药学论文 畜牧兽医 中医学 临床医学 外科学 内科学 生物制药 基础医学 预防卫生 肿瘤论文 儿科学论文 妇产科 遗传学 其他医学
经济论文
国际贸易 市场营销 财政金融 农业经济 工业经济 财务审计 产业经济 交通运输 房地产经济 微观经济学 政治经济学 宏观经济学 西方经济学 其他经济 发展战略论文 国际经济 行业经济 证券投资论文 保险经济论文
法学论文
民法 国际法 刑法 行政法 经济法 宪法 司法制度 法学理论 其他法学
计算机论文
计算机网络 软件技术 计算机应用 信息安全 信息管理 智能科技 应用电子技术 通讯论文
会计论文
预算会计 财务会计 成本会计 会计电算化 管理会计 国际会计 会计理论 会计控制 审计会计
文学论文
中国哲学 艺术理论 心理学 伦理学 新闻 美学 逻辑学 音乐舞蹈 喜剧表演 广告学 电视电影 哲学理论 世界哲学 文史论文 美术论文
管理论文
行政管理论文 工商管理论文 市场营销论文 企业管理论文 成本管理论文 人力资源论文 项目管理论文 旅游管理论文 电子商务管理论文 公共管理论文 质量管理论文 物流管理论文 经济管理论文 财务管理论文 管理学论文 秘书文秘 档案管理
社科论文
三农问题 环境保护 伦理道德 城镇建设 人口生育 资本主义 科技论文 社会论文 工程论文 环境科学