前言

前面4节我们已经完成了对4种C++对象布局的分析,本文试图覆盖更多的,常见的C++面向对象的概念。所以,最后2节将继续阐述2个主题:接口和抽象类以及构造函数、虚构函数和虚析构函数。

接口

这里我准备只主要阐述接口,而不谈一般的抽象类。因为在C++中,是没有“接口”这种类型的,所有的接口事实上是定义为纯抽象类。所谓纯抽象类,就是没有 成员变量,没有实现了的函数,只有纯虚函数的抽象类。我相信,理解了接口这种特殊的抽象类,再去理解一般的抽象类是很容易的。

来看一个例子,我们有接口IAnimal来表示一般的动物行为,代码如下:

class IAnimal
{
public:
    virtual void Eat()=0;
    virtual void Move()=0;
    virtual void Sleep()=0;
};

这个接口在内存中的布局可以看作下图中的样子:

接口在内存中的布局可以看作一个虚函数指针指向一个虚函数表,虚函数表中的所有元素指向的地址为0,因为所有纯虚函数都没有被实现。

上面的描述只是为了大家理解方便,事实上这种说法是很不准确的。因为,一个接口是绝对不能被构造的,这一点很重要。接口中的纯虚函数都没有被实现,如果允许构造他们,那么在调用这些方法的时候,将造成非法访问异常。

我们的问题来了,既然接口不允许被构造,那么我们为什么经常看到各种接口类型的对象呢。很简单,这些接口类型的对象都是由从该接口继承的子类对象通过类型 转换而来的。在子类中,我们需要实现接口的所有方法,否则,该子类仍是一个抽象类。下图中,我们描述了继承了IAnimal接口的Horse类的内存结构 图,这个类还继承了IVehicle接口:

关于Horse类如果进行指针调整,怎么转换为IAnimal接口类型,并实现多态特性的,我们在前面的章节中不止一次涉及到,即使是接口,也没有什么不同,我们这里不打算再重复。

下面,我们要谈的是,为什么我们要使用接口呢? 由于本文主要研究的是对象的内存布局,所以,关于这个涉及设计模式的主题,我只准备简单的讲述,这个主题太大了,因此我只希望下面的描述能给你一些关于接 口应用场景的灵感。我们经常听到关于接口的描述是“只要实现了某某接口,对象就能实现某某功能/流程”,或者“就能被某某方法/模块调用来实现某某功能 /流程”。 我们来看下面的代码:

void AnimalHappyDay(IAnimal* animal)
{
    animal->Eat();
    animal->Move();
    animal->Sleep();
}

类似的,我们要说,任何类只要实现了IAnimal接口,AnimalHappyDay函数就可以调用该类的对象,来实现动物快乐的一天!我们不用关心这 个类是猫,狗还是独角兽,不用关心它是否还实现了其他的接口,不用关心它是直接实现IAnimal接口的,还是间接的。他们只有一个共同点,就是实现了 IAnimal接口。那么,它就可以被AnimalHappyDay函数调用,Eat,Move,Sleep,来实现动物快乐的一天这个功能。

一个接口,应该是最小粒度的。所谓最小粒度,首先,它没有任何的实现,只是用来描述一种标准的调用规范,完全由子类去实现它。其次,它只包含实现流程需要 的最小的方法集合,比如,我们在IAnimal接口中不应该加入Grow方法,因为AnimalHappyDay流程不需要该方法,如果我们加入Grow 方法,所有继承IAnimal的类就不得不去实现它。应该把Grow方法放在其他接口中,比如ILIfe接口,这个接口中或许定义了Both,Dead方 法,用来实现动物的生命周期,类作者可以选择是否要去实现该接口。

转载于:https://blog.51cto.com/sensen/740283

C++对象的内存分析(5)相关推荐

  1. C++对象的内存分析(2)

    C++对象的内存分析(2) Binhua Liu 前言 本章节讨论单继承情况下类对象的内存特性.阅读时请思考这几个问题:从子类到基类的类型转换,编译器做了什么?多态是怎么实现的?类的成员函数(包括虚函 ...

  2. java转型 内存_java 对象转型内存分析

    对象转型: 一个基类的引用类型变量可以指向其子类的对象(要求传个动物,传给狗是可以的,狗是动物) 一个基类的引用不可以访问其子类对象的新增成员(狗会游泳不代表所有的动物都会游泳,把狗当作动物来看时不可 ...

  3. C++对象的内存分析(4)

    前言 本章节是4个课题的最后一个,我们将讨论多重继承情况下,对象内存的布局.阅读本文,请思考下面的问题:当子类从多个基类继承,虚函数指针和成员变量将如何布局?编译器如何进行子类和基类之间类型转换?如果 ...

  4. 由static_cast和dynamic_cast到C++对象占用内存的分析

    static_cast和dynamic_cast是C++的类型转换操作符.编译器隐式执行的任何类型转换都可以由static_cast显式完成,即父类和子类之间也可以利用static_cast进行转换. ...

  5. Java中的内存分析

    分析内存是深入了解编程的第一步,以下来演示一下编程中常见的内存分析,文章脉络: 数据类型 数据类型不同,内存分配位置和大小也不同,用一张图表示Java中的数据类型.除了基本数据类型,其它全部是引用类型 ...

  6. JVM学习笔记之-堆,年轻代与老年代,对象分配过程,Minor GC、Major GC、Full GC,堆内存大小与OOM,堆空间分代,内存分配策略,对象分配内存,小结堆空间,逃逸分析,常用调优工具

    堆的核心概述 概述 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域.Java堆区在JVM 启动的时候即被创建,其空间大小也就确定了.是JVM管理的最大一块内存空间. 堆内存的大小是可 ...

  7. 源码分析:Java对象的内存分配

    Java对象的分配,根据其过程,将其分为快速分配和慢速分配两种形式,其中快速分配使用无锁的指针碰撞技术在新生代的Eden区上进行分配,而慢速分配根据堆的实现方式.GC的实现方式.代的实现方式不同而具有 ...

  8. 6.面向对象,构造器,递归以及对象创建时内存分析(内含代码与练习)

    面向对象的概念以及特征 概念 实质上将 "数据" 与 "行为" 的过程, 以类的形式封装起来, 一切以 对象 为中心的 面向对象的程序设计过程中有两个重要概念: ...

  9. (转)c++对象内存分析4

    前言    本章节是4个课题的最后一个,我们将讨论多重继承情况下,对象内存的布局.阅读本文,请思考下面的问题:当子类从多个基类继承,虚函数指针和成员变量将如何布局?编译器如何进行子类和基类之间类型转换 ...

最新文章

  1. 【小白学PyTorch】10.pytorch常见运算详解
  2. python使用pandas计算dataframe中每个分组的分位数极差、分组数据的分位数极差(range)、使用groupby函数和agg函数计算分组的两个分位数
  3. MySQL利用xtrabackup进行增量备份详细过程汇总
  4. webgl坐标转换_OpenGL/WebGL顶点坐标变换过程简介
  5. 2016 博客导读总结 amp; 个人感悟
  6. python3-numpy IO load()、save()、savez()、loadtxt()、savetxt()、tofile()、fromfile()
  7. mysql 建前缀索引_MySQL_前缀索引_建立
  8. python程序设计教程胡建华_Python程序设计教程
  9. 1120. Friend Numbers (20)-PAT甲级真题
  10. LR11.0 下载及破解
  11. 【Java实验】文件中单词重复字母对的查找
  12. CrazyBox常见问题
  13. 智能体重秤方案/案列/APP/小程序
  14. 《黑客与画家》摘要读后感
  15. 月盈利百万的茶馆是如何通过一套商业模式起家?方案分享!
  16. 使用canvas 代码画小猪佩奇
  17. 路由器DMZ简单解说
  18. <Android开发> Android vold - 第七篇 vold 的runCommand()方法解析
  19. angularjs与jquery特效slidetoggle结合
  20. 计算机学科学年论文方向,计算机学年类论文选题 计算机学年论文题目怎么拟...

热门文章

  1. JBoss 类加载器问题解决
  2. jbpm 4.3 与 spring 集成
  3. 【五线谱】还原记号 ( 还原记号使用简介 | 变音记号、还原记号实例分析 )
  4. 【C 语言】字符串操作 ( strlen 与 sizeof 函数 | 计算 字符串长度 与 内存块大小 )
  5. 【Flutter】Flutter 混合开发 ( 安卓端向 Flutter 传递数据 | FlutterFragment 数据传递 | FlutterActivity 数据传递 )
  6. 【计算理论】可判定性 ( 计算模型与语言 | 区分 可计算语言 与 可判定语言 | 证明 通用图灵机语言是 可计算语言 | 通用任务图灵机 与 特殊任务图灵机 )
  7. 【Android 安全】DEX 加密 ( Application 替换 | Android 应用启动原理 )
  8. 【Android 内存优化】Android Profiler 工具常用功能 ( 监测内存 | 内存快照 )
  9. 【Android FFMPEG 开发】Android Studio 中 配置 FFMPEG 库最小兼容版本 ( undefined reference to 'atof' )
  10. 【Java 并发编程】CountDownLatch 简介