什么是EBC和EBO
什么是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相关推荐
- boost::hana::detail::ebo用法的测试程序
boost::hana::detail::ebo用法的测试程序 实现功能 C++实现代码 实现功能 boost::hana::detail::ebo用法的测试程序 C++实现代码 #include & ...
- 数字时代的抉择,金蝶 EBC 的破局
今年 10 月,Gartner 发布了企业在 2021 年需要关注的重要战略科技趋势,其中"可组装的企业"一词引起热议.Gartner 认为原本为了提高效率而建立的静态业务流程很脆 ...
- 2021金蝶全球创见者大会成功举办, 500强企业共话EBC数字战斗力
11月27日,由金蝶主办的"2021全球创见者大会"成功举办.大会以"用数字战斗力,向管理要效益"为主题,求索不确定时代,EBC如何帮助500强及中小企业拥抱数 ...
- ebc是什么意思_什么是亚马逊EBC,EBC有什么用?
原标题:什么是亚马逊EBC,EBC有什么用? 近期,有很多人在文中提到EBC,或者问小编EBC是什么还有不少品牌卖家发现后台多了一个新功能Enhanced Brand Content(图文版品牌描述) ...
- LearnGL - 03 - DrawQuad - VBO/EBO - 理解 CW, CCW 的正背面
文章目录 如何绘制? 先画第一个直角三角形 绘制效果 再画第二个直角三角形 绘制效果 查看正面的顺/逆时针 使用 索引缓存 EBO/IBO 来节省显存 重新计算显存顶点+索引用量 索引缓存 EBO/I ...
- QT OpenGL(一 VAO、VBO、EBO使用)
1.什么是OpenGL? Open Graphics Library,它是一个由Khronos组织制定并维护的规范 OpenGL核心是一个C库,同时也支持多种语言的派生 核心模式 也叫可编程管线,提供 ...
- OPenGL 学习笔记之 VAO VBO EBO 以及SHADER 并使用其绘制三角形
译注 在学习此节之前,建议将这三个单词先记下来: 顶点数组对象:Vertex Array Object,VAO 顶点缓冲对象:Vertex Buffer Object,VBO 索引缓冲对象:Eleme ...
- 【OpenGL学习笔记五】 索引缓冲对象EBO
在绘制一些图形的时候比如正方体,正方体的顶点是有很多重合的,如果为每个顶点都分配内存那么就比较浪费内存了. OpenGL通过索引缓冲对象来解决这个问题,做到重复的顶点只需要分配一次内存,再绘图的时候后 ...
- 外汇市场百年风云演变,当代“钱”途之选就看EBC金融集团
随着外汇交易的发展,越来越多的人开始学习和投资外汇交易.可是你知道外汇的起源吗? 现代外汇的起源于1850年代的美国,一家名为Alexander Brown & Sons的公司开始交易外汇,它 ...
最新文章
- Ubuntu 17.04 编译安装 Nginx 1.9.9 配置 https 免费证书
- 反三角函数怎么表示_交流电的功率因数怎么算(里面有例子)
- python ftp timeout_python - FTP文件传输期间Python数据通道超时 - 堆栈内存溢出
- bat截取字符串[转]
- 在 Nginx 上支持 HTTP/3
- 【redis】redis 各种数据类型应用和实现方式
- excel日期格式改不了_画进度计划横道图,Excel就够了
- iOS - Animation 八种方法
- C++容器删除数据时迭代器失效
- 易语言exe读写游戏例程源码_游戏工作室建立三步曲2019:脚本、防封与人工智能...
- 葵花8号卫星数据简介与下载(一)——数据介绍与FTP下载
- php将请求转发,PHP中实现请求转发(curl)和请求重定向
- 【智能优化算法】广义邻域搜索算法(综述)
- 一辆智能小车,最初(时间为0)的位置为(0,0),我们想知道它最后的位置。小车以每小时10公里的速度向北移动(以北为y轴正向,以东为x轴正向)。小车会受到一系列依照时间戳记排序的命令,1表示“向左转”
- FBG光纤光栅反射器的特点
- 网页图标/images/favicon.ico type=image/x-icon /
- 多年经验的程序员迷失了自己,该怎么办
- 本地连接ipv4无网络访问权限解决办法
- -bash: java: command not found (Linux)
- 中国RISC-V机遇与变革下,赛昉科技发布两款高性能新品