C++ 空白基类最优化(EBO 或 EBCO)

对于c++中的一个空类

class X

{

};

事实上并不是空的,sizeof(X)并不等于0, 一般的结果是1。每个X的对象都有一个隐晦的1 bytes,是被编译器安插进去的一个char,这样可以使得这个class的两个objects在内存中配置独一无二的地址。

当X作为另一个类的成员时,如:

class A

{

public:

X x;

int a;

};

由于X占一个字节,int占4个字节,再加上编译器的alignment调整,sizeof(Y) = 8。

但是当一个类继承X时:

class Y : public X

{

public:

int a;

};

这时大部分编译器对于sizeof(Y)的结果是4,而不是8。这就是所谓的空白基类最优化在(empty base optimization-EBO 或 empty base class opimization-EBCO)。在空基类被继承后由于没有任何数据成员,所以子类优化掉基类所占的1 byte。EBO并不是c++标准所规定必须的,但是大部分编译器都会这么做。

下面是做的测试

#include<iostream>

using namespace std;

class Empty
{};

class Son1:public Empty
{};

class Component
{
  int x;
  Empty t;
};

class Son2:public Empty
{
  int x;
};

int main()
{
   Empty t;

   printf("size of Empty: %d\n",sizeof(Empty));//1,被编译器安插进去的一个char,这样可以使得这个class的两个objects在内存中配置独一无二的地址
   printf("size of t: %d\n",sizeof(t));        //1
   printf("size of Son1: %d\n",sizeof(Son1));  //1
   printf("size of Component: %d\n",sizeof(Component));  //8,字节对齐
   printf("size of Son2: %d\n",sizeof(Son2));  //4,空白基类最优化 

   system("pause");
   return 0;
}

参考:http://blog.csdn.net/luckyxiaoqiang/article/details/8494235

有人可能会问是否需要考虑this指针?

我觉得是不需要考虑的。首先看一下this指针的定义:C++ this 指针。this 指针是作为参数传递给每个成员变量的。它是指向本类对象的指针,它的值是当前被调用的成员函数所在的对象的起始地址。也就是说this指针是不存在于成员变量中的。

时间: 2024-08-30 01:09:22

C++ 空白基类最优化(EBO 或 EBCO)的相关文章

《Programming WPF》翻译 第9章 2.选择一个基类

原文:<Programming WPF>翻译 第9章 2.选择一个基类 WPF提供了很多类,当创建一个自定义元素时,你可以从这些类中派生.图9-1显示了一组可能作为类--可能是合适的基类,并且说明了他们之间的继承关系.注意到,这决不是完整的继承关系图,只是简单的显示了一些你应该考虑的可能的基类. 无论你选择了哪一个基类,你的元素都会直接或间接地从FrameworkElement派生.这将提供routing事件,高级属性处理,动画,数据绑定,外观上的支持,样式,以及逻辑树的集成. 派生于Fram

当this指针成为指向之类的基类指针时,也能形成多态

this指针: 1)对象中没有函数,只有成员变量 2)对象调用函数,通过this指针告诉函数是哪个对象自己谁. 1 #include<iostream> 2 using namespace std; 3 class Shape 4 { 5 public: 6 //void cal_display(Shape* this) 7 void cal_display(){ 8 display(); 9 this->display(); 10 } 11 private: 12 virtual vo

基于MVC4+EasyUI的Web开发框架形成之旅--基类控制器CRUD的操作

在上一篇随笔中,我对Web开发框架的总体界面进行了介绍,其中并提到了我的<Web开发框架>的控制器的设计关系,Web开发框架沿用了我的<Winform开发框架>的很多架构设计思路和特点,对Controller进行了封装.使得控制器能够获得很好的继承关系,并能以更少的代码,更高效的开发效率,实现Web项目的开发工作,整个控制器的设计思路如下所示. 从上图的设计里面可以看到,我把主要能通过抽象封装的CRUD方法都放到了BusinessController<B, T>类里面,

C++中虚基类

摘自<C++程序设计> 如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多份同名成员. C++提供虚基类(virtual base class)的方法,使得在继承间接共同基类时只保留一份成员. 下面举例说明: 在如下的图中: Person类是Student和Teacher的基类,而Graduate类又继承自Student和Teacher类. 如果使用虚基类的话,Graduate将有两份age拷贝,两份gender拷贝,两份name

UI(UGUI)框架(二)-------------UIManager单例模式与开发BasePanel面板基类/UIManage统一管理UI面板的实例化/开发字典扩展类

UIManage单实例: 1 /// 单例模式的核心 2 /// 1,定义一个静态的对象 在外界访问 在内部构造 3 /// 2,构造方法私有化 4 5 private static UIManager _instance; 6 7 public static UIManager Instance 8 { 9 get 10 { 11 if (_instance == null) 12 { 13 _instance = new UIManager(); 14 } 15 return _instan

从设计基类及其派生类看继承关系

继承能够定义可重用.扩展或修改父类行为的子类.但基类的静态构造函数.实例构造函数和析构函数不能被派生类继承. 在下面实例中,定义一个基类Publication用于表示任何类型的出版物以及派生至Publication的其他类型Book类,由此也可以扩展为定义其他类型如:Magazine.Journal.Newspaper和Article. 在设计基类Publication时我们必须考虑到如下关系: 1.要在基类中添加哪些成员 2.基类是否用作派生类模板的抽象基类 3.类层次结构的扩展空间大小,要开

EF增删查改基类

/// <summary> /// EF DAL CURD基类 /// </summary> /// <typeparam name="T"></typeparam> public class BaseDAL<T> where T : class, new() { /// <summary> /// 上下文网关 /// </summary> protected SchoolEntities db = n

派生类和基类的转换

指针引用分四种情况: 1.直接用基类指针引用基类对象 2.直接用派生指针引用派生对象 3.由基类指针引用派生类对象,由于派生类也是基类对象(包含关系),所以这种引用是安全的.但是只能引用基类成员,若试图通过基类指针引用那些只在派生类中才有的成员,编译器会报告语法错误.(解决该问题的答案是虚函数和多态性) 4.用派生类指针引用基类对象,这种方式会导致编译器报错.必须先把派生类指针强制转换成基类指针. 如果基类和派生类都定义了同名函数,通过对象指针调用成员函数时,到底调用哪里的函数由指针的原始类型决

第六篇:为多态基类声明虚析构函数

前言 在很多类中,可以看到其析构函数都是声明为虚函数的. 那么,为何要将析构函数声明为虚函数?哪些情况要将析构函数声明为虚函数? 本文将为你解惑. 在使用 C++ 实现多态的时候,有一点一定要清楚:当派生类对象经由基类指针被删除,而此基类的析构函数没有被声明为虚函数的话,那么析构函数只会释放基类部分的成员而无视派生类成员. 如果不对这一点加以防范,那么很多时候,会带来内存泄露这样灾难性的后果. 问题描述 假设,有以下几个类,分别代表:钟,原子钟,水钟,腕表: 1 // 钟 2 class Tim