什么是EBC和EBO
    EBC英文全称为“Empty Base Class”,中文全称“空基类”。那什么是空基类呢?简单的
说就是没有任何数据成员的类就称之为空基类。也就是EBC的类定义中不包含任何数据成员,
那么这样一来可能大家会认为一个EBC的尺寸(sizeof)因该是0,确实按照定义而言因该是
这样的,但是我们知道即使是一个EBC也可以定义一个对象,而对象是一个运行时的内存实
体,也就是说对象是必须要能够通过内存地址进行区分的,那么即使是一个EBC类的对象也
必须占有内存空间,这样一来一般情况下编译器会将EBC的尺寸看作1字节,也就是让其对象
占用一个字节的空间,这样一来既可以达到对象的地址鉴别,同时也是一个比较节约内存的
分配策略。例如:
        #include <cassert>
        
        struct CEmptyClass {};
        int main( int argc, char *argv[] )
        {
            CEmptyClass emptyObject;
            assert( sizeof( CEmptyClass ) == 1 );
            assert( sizeof( emptyObject ) == 1 );
            
            return 0;
        }
    通过上面的讨论已经知道什么是空基类了,那么下面这些的类属于空基类么?
        struct CEmptyClass1 { CEmptyClass1() {}; ~CEmptyClass1() {} };
        struct CEmptyClass2 { void print() {} };
        struct CEmptyClass3 { virtual ~CEmptyClass3() {} };
        struct CEmptyClass4 : public CEmptyClass1 {};
        struct CEmptyClass5 : public CEmptyClass3 {};
        struct CEmptyClass6 { uint32_t v; };
        struct CEmptyClass7 : public CEmptyClass6 {};
        
        struct CEmptyClass10 : virtual public CEmptyClass1 {};
        struct CEmptyClass11 : virtual public CEmptyClass1 {};
        struct CEmptyClass12 : public CEmptyClass10, public CEmptyClass11 {};
        
    根据上面的定义“没有任何数据成员”,这里的数据成员不仅仅包括类的成员变量,同
时还包括编译器为了某种目的引入的数据成员,比如:为了支持多态而引入的虚指针vptr、
为了支持虚继承而引入的必要的虚基类指针等,而且还包括从基类继承直接或间接继承而
来的上述的数据成员。那么这样一来,上面的问题就很清楚了,CEmptyClass3、
CEmptyClass5、CEmptyClass6、CEmptyClass7、CEmptyClass10、CEmptyClass11、
CEmptyClass12就不是EBC了,而CEmptyClass1、CEmptyClass2、CEmptyClass4仍然是EBC。
    那么可能有些人会看出来如果这样的一个类,他的尺寸是多少呢?
        struct CEmptyClass20 : public CEmptyClass1, public CEmptyClass2 {};
        struct CEmptyClass21 : public CEmptyClass1 { uint32_t v; };
        struct CEmptyClass22 : public CEmptyClass1, public CEmptyClass2 { uint32_t v; };
        struct CEmptyClass23 : public CEmptyClass1, public CEmptyClass6 {};
    在VC++8和g++3.4.x(g++4以上版本编译上述代码出现编译错误)版本时所出现的结果
会比较出人意料:
        sizeof( CEmptyClass20 ) == 1
        sizeof( CEmptyClass21 ) == 4
        sizeof( CEmptyClass22 ) == 8
        sizeof( CEmptyClass23 ) == 4
    为什么会出现上述的结果呢?这个主要是因为编译器实施EBO所致的。那什么是EBO呢?
EBO英文全称“Empty Base Class Optimize”,中文全称“空基类优化”。其实就是在EBC类被
继承的是时候由于空基类没有任何数据成员所以可以让其在子类的对象布局中优化掉EBC所
占用的那一个字节,用子类对象的首地址作为EBC的子对象的首地址(也就是this指针)。
需要注意的是并不是每一次EBO优化都回被成功的实施,有时候由于继承关系和对象布局
问题会导致无法实施EBO优化,从而导致EBC的子对象必然会在子类的对象中占用一定的空
间(一般会大于1个字节,主要是因为内存对齐的需要)。
    我们来分析上面的的4个继承类的尺寸现象问题:
    1. sizeof( CEmptyClass20 ) == 1;CEmptyClass20类继承于两个EBC类,同时自己也
       是一个EBC类,所以编译器会自动地优化掉两个基类的子对象的内存空间,所以尺寸
       仍然是1字节;
    2. sizeof( CEmptyClass21 ) == 4;CEmptyClass21类继承于一个EBC类,同时自己也
       包含一个4字节的成员变量,此时可以成功的实施EBO优化将EBC的内存空间优化掉;
    3. sizeof( CEmptyClass22 ) == 8;CEmptyClass22类继承于两个EBC类,同时自己也
       包含一个4字节的成员变量,按一般常理而言此时编译器应该可以优化掉两个EBC所
       需要的内存空间,从而使得其尺寸仅仅只有4个字节,可是为什么会有8个字节呢?
       也就是说此时编译器并没有实施EBO优化,使得每一个EBC子对象都回占用1个字节的
       内存,从而占用2字节内存,再加上32位系统下的对齐需要填充2个字节已形成4字节
       对齐,所以会导致其成为8个字节;
    4. sizeof( CEmptyClass23 ) == 4;CEmptyClass23类继承于一个EBC类和一个非EBC类,
       而CEmptyClass6因为含有一个vptr所以具有4字节尺寸,而CEmtpyClass23内本身不
       包含任何数据成员,通过EBO优化掉第一个EBC的内存,所以其尺寸就是4字节。
    通过上面的分析可以看出来,一般情况下如果子类的基类列表中只有一个EBC时时一定
可以成功实施EBO优化的,而如果出现多继承于多个EBC时会根据子类是否包含数据成员而
确定能够实施EBO优化,同时会和编译器的优化策略具有较大的关系。
    在boost库中有非常多的机制依赖于EBO优化,比如:nocopyable等,充分的理解EBC/EBO
并利用其所具有的内存优化特征,会在类继承体系中引入行为/策略的同时不导致对象的膨胀。

什么是EBC和EBO相关推荐

  1. boost::hana::detail::ebo用法的测试程序

    boost::hana::detail::ebo用法的测试程序 实现功能 C++实现代码 实现功能 boost::hana::detail::ebo用法的测试程序 C++实现代码 #include & ...

  2. 数字时代的抉择,金蝶 EBC 的破局

    今年 10 月,Gartner 发布了企业在 2021 年需要关注的重要战略科技趋势,其中"可组装的企业"一词引起热议.Gartner 认为原本为了提高效率而建立的静态业务流程很脆 ...

  3. 2021金蝶全球创见者大会成功举办, 500强企业共话EBC数字战斗力

    11月27日,由金蝶主办的"2021全球创见者大会"成功举办.大会以"用数字战斗力,向管理要效益"为主题,求索不确定时代,EBC如何帮助500强及中小企业拥抱数 ...

  4. ebc是什么意思_什么是亚马逊EBC,EBC有什么用?

    原标题:什么是亚马逊EBC,EBC有什么用? 近期,有很多人在文中提到EBC,或者问小编EBC是什么还有不少品牌卖家发现后台多了一个新功能Enhanced Brand Content(图文版品牌描述) ...

  5. LearnGL - 03 - DrawQuad - VBO/EBO - 理解 CW, CCW 的正背面

    文章目录 如何绘制? 先画第一个直角三角形 绘制效果 再画第二个直角三角形 绘制效果 查看正面的顺/逆时针 使用 索引缓存 EBO/IBO 来节省显存 重新计算显存顶点+索引用量 索引缓存 EBO/I ...

  6. QT OpenGL(一 VAO、VBO、EBO使用)

    1.什么是OpenGL? Open Graphics Library,它是一个由Khronos组织制定并维护的规范 OpenGL核心是一个C库,同时也支持多种语言的派生 核心模式 也叫可编程管线,提供 ...

  7. OPenGL 学习笔记之 VAO VBO EBO 以及SHADER 并使用其绘制三角形

    译注 在学习此节之前,建议将这三个单词先记下来: 顶点数组对象:Vertex Array Object,VAO 顶点缓冲对象:Vertex Buffer Object,VBO 索引缓冲对象:Eleme ...

  8. 【OpenGL学习笔记五】 索引缓冲对象EBO

    在绘制一些图形的时候比如正方体,正方体的顶点是有很多重合的,如果为每个顶点都分配内存那么就比较浪费内存了. OpenGL通过索引缓冲对象来解决这个问题,做到重复的顶点只需要分配一次内存,再绘图的时候后 ...

  9. 外汇市场百年风云演变,当代“钱”途之选就看EBC金融集团

    随着外汇交易的发展,越来越多的人开始学习和投资外汇交易.可是你知道外汇的起源吗? 现代外汇的起源于1850年代的美国,一家名为Alexander Brown & Sons的公司开始交易外汇,它 ...

最新文章

  1. DocumentsContract cannot be resolved
  2. java并发实战看不懂,附带学习经验
  3. 让bind函数支持IE8浏览器的方法
  4. 0001-Hello world(第一弹)
  5. 用户空间使用内核头文件
  6. php框架laravel百科,PHP 的Laravel 框架
  7. 亚马逊S3文件存储的可视化
  8. Oracle 坏块 总结
  9. JDBC数据库编程手记(2)
  10. 9 个将改变一切的物联网应用
  11. 论文浏览(45) MiCT: Mixed 3D/2D Convolutional Tube for Human Action Recognition
  12. 图片太大上传不了怎么缩小?jpg图片压缩大小的方法
  13. 干草堆[单调队列优化DP]
  14. VUE项目中安装和使用vant组件
  15. Android 仿微信群聊头像
  16. Layui-五星好评
  17. 创建一个图文并茂的调查
  18. SpringBoot 中的验证码、二维码、缩略图、图片上传、定时器调度
  19. 圆周分孔计算公式表图_在圆上分孔怎么计?
  20. 高中数学必修3知识点总结归纳:第一章算法初步

热门文章

  1. 西安三本哪个计算机学校最好,西安三本大学前十名 西北大学现代学院仅第四...
  2. 基因调控分析之非编码RNA
  3. iCheck设置选中/取消选中
  4. python+opencv 实现图像人脸检测及视频中的人脸检测
  5. php排序数组排序_php简单实现多维数组排序的方法
  6. 点击a标签打开新窗口
  7. 2022 CocoaPods安装教程
  8. 基于jsp+mysql+Spring+mybatis+Springboot的SpringBoot婚纱影楼摄影预约网站
  9. 随机森林的几个重要参数
  10. linux CFI接口,高手进阶 Linux系统下MTD/CFI驱动介绍