There are many factors that decide the size of an object of a class in C++. These factors are:

  1. Size of all non-static data members     //静态数据成员的大小
  2. Order of data members                        //数据成员的顺序
  3. Byte alignment or byte padding         //字节校正、对齐
  4. Size of its immediate base class         //基类的大小
  5. The existence of virtual function(s) (Dynamic polymorphism using virtual functions).          //是否存在虚函数
  6. Compiler being used          使用的编译器
  7. Mode of inheritance (virtual inheritance)  继承模型(虚继承)

Size of all non-static data members

Only non-static data members will be counted for calculating sizeof class/object.

class A {
private:
float iMem1;
const int iMem2;
static int iMem3;
char iMem4;
};

For an object of class A, the size will be the size of float iMem1 + size of int iMem2 + size of char iMem3. Static members are really not part of the class object. They won't be included in object's layout.  <2>Order of data members The order in which one specifies data members also alters the size of the class.

class C {
char c;
int int1;
int int2;
int i;
long l;
short s;
};

The size of this class is 24 bytes. Even though char c will consume only 1 byte, 4 bytes will be allocated for it, and the remaining 3 bytes will be wasted (holes). This is because the next member is an int, which takes 4 bytes. If we don't go to the next (4th) byte for storing this integer member, the memory access/modify cycle for this integer will be 2 read cycles. So the compiler will do this for us, unless we specify some byte padding/packing.

If I re-write the above class in different order, keeping all my data members like below:

class C {
int int1;
int int2;
int i;
long l;
short s;
char c;
};

Now the size of this class is 20 bytes.

In this case, it is storing c, the char, in one of the slots in the hole in the extra four bytes.

Byte alignment or byte padding

As mentioned above, if we specify 1 byte alignment, the size of the class above (class C) will be 19 in both cases.

Size of its immediate base class

The size of a class also includes size of its immediate base class.

Lets take an example:

Class B {
...
int iMem1;
int iMem2;
} Class D: public B {
...
int iMem;
}

In this case, sizeof(D) is will also include the size of B. So it will be 12 bytes.

The existence of virtual function(s)

Existence of virtual function(s) will add 4 bytes of virtual table pointer in the class, which will be added to size of class. Again, in this case, if the base class of the class already has virtual function(s) either directly or through its base class, then this additional virtual function won't add anything to the size of the class. Virtual table pointer will be common across the class hierarchy. That is

class Base {
public:
...
virtual void SomeFunction(...);
private:
int iAMem
}; class Derived : public Base {
...
virtual void SomeOtherFunction(...);
private:
int iBMem
};

In the example above, sizeof(Base) will be 8 bytes--that is sizeof(int iAMem) + sizeof(vptr). sizeof(Derived) will be 12 bytes, that is sizeof(int iBMem) + sizeof(Derived). Notice that the existence of virtual functions in class Derived won't add anything more. Now Derived will set the vptr to its own virtual function table.

Compiler being used

In some scenarios, the size of a class object can be compiler specific. Lets take one example:

class BaseClass {
int a;
char c;
}; class DerivedClass : public BaseClass {
char d;
int i;
};

If compiled with the Microsoft C++ compiler, the size of DerivedClass is 16 bytes. If compiled with gcc (either c++ or g++), size of DerivedClass is 12 bytes.

The reason for sizeof(DerivedClass) being 16 bytes in MC++ is that it starts each class with a 4 byte aligned address so that accessing the member of that class will be easy (again, the memory read/write cycle).

Mode of inheritance (virtual inheritance)

In C++, sometimes we have to use virtual inheritance for some reasons. (One classic example is the implementation of final class in C++.) When we use virtual inheritance, there will be the overhead of 4 bytes for a virtual base class pointer in that class.

class ABase{
int iMem;
}; class BBase : public virtual ABase {
int iMem;
}; class CBase : public virtual ABase {
int iMem;
}; class ABCDerived : public BBase, public CBase {
int iMem;
};

And if you check the size of these classes, it will be:

  • Size of ABase : 4
  • Size of BBase : 12
  • Size of CBase : 12
  • Size of ABCDerived : 24

Because BBase and CBase are dervied from ABase virtually, they will also have an virtual base pointer. So, 4 bytes will be added to the size of the class (BBase and CBase).  That is sizeof ABase + size of int + sizeof Virtual Base pointer.

Size of ABCDerived will be 24 (not 28 = sizeof (BBase + CBase + int member)) because it will maintain only one Virtual Base pointer (Same way of maintaining virtual table pointer).
大小为24,因为它只有一个虚基类指针;

分析:
以上都经过验证,一定正确,但是还有一些值得注意的问题,主要是两个,一个是虚函数、一个是虚继承;
1. 通常情况下,虚函数的一搬继承中,不在计算基类中虚函数的大小,以为一个类中只有一个虚函数表;

2. 虚继承相对就比较复杂一些,虚继承中的问题主要是,当前基类的大小,加上现在类的大小,同时还要加上一个虚指针,这个虚指针式指向虚函数的,所以相当于额外加上4,但是还要遵循第一个的条件,一个函数中只能有一个虚指针,一个虚指针表,所以在计算时要注意,每一个函数都只有一个自己的虚指针!

http://blog.sina.com.cn/s/blog_6a18dd270100n1rc.html

sizeof(class)分析相关推荐

  1. linux下enum类型占几个字节,第11课 - enum, sizeof, typedef 分析

    第11课 - enum, sizeof, typedef 分析 1. enum介绍 (1)enum是C语言中的一种自定义类型,和struct.union地位相同,格式如下: // enum每个值的最后 ...

  2. c++中包含empty virtual base class 类的sizeof结果分析

    背景 类的继承关系如下 class Base{}; class First:public virtual Base{}; class Second:public virtual Base{}; cla ...

  3. memset(G, 0x3f, sizeof(G))涵义

    1 当我们想将某个数组全部赋值为无穷大时 (例如解决图论问题时邻接矩阵的初始化) memset(G, 0x3f, sizeof(G)) 分析: 最精巧的无穷大常量取值是0x3f3f3f3f, 它的十进 ...

  4. 带你一起拿下strlen和sizeof(C语言系列17)

    目录 前言: 知识点回顾: strlen: sizeof: 数组名: 实战演练: 一维数组: 1.int a[] = {1,2,3,4}对于sizeof的分析. 2.char arr[] = {'a' ...

  5. 关于共用体所占的内存空间的问题

    共用体 `共用体(联合)` 共用体类型变量的定义 共用体变量的引用方式 共用体类型数据的特点 [例1]分析程序运行结果 [实训内容3]输入并运行以下程序,从输出的结果体会"共用"的 ...

  6. BaiDu往年面试题目汇总☆WM☆

    BaiDu往年面试题目汇总☆WM☆祝自己明天能取得一个好的面试成绩 题目来源:http://www.cnblogs.com/cutepig/archive/2007/09/14/893552.html ...

  7. 用对齐原则求结构体长度

    用对齐原则求结构体长度 [日期:2009-09-18] 来源:中嵌信息  作者:chinaeda-news [字体:大 中 小] 1. 熟悉Win32下VC6.0各种基本数据长度: size of i ...

  8. C++之字节对齐与结构体大小

    说明: 结构体的sizeof值,并不是简单的将其中各元素所占字节相加,而是要考虑到存储空间的字节对齐问题.这些问题在平时编程的时候也确实不怎么用到,但在一些笔试面试题目中出是常常出现, 一.解释 现代 ...

  9. 数组名和取数组名的区别

    先来个简单的小案例 #include <stdio.h> #include <iostream>using namespace std;int main() {int a[10 ...

最新文章

  1. python中isinstance(3、object)_Python中为什么推荐使用isinstance来进行类型判断?而不是type...
  2. 编程爱好者学vb还是python-Python语言为什么被称为高级程序设计语言?
  3. mysql myisam存储引擎_MySQL浅谈MyISAM存储引擎
  4. ECCV 2020 DETR:《End-to-End Object Detection with Transformers》论文笔记
  5. AcWing - 171 送礼物(双向dfs)
  6. 飞天2.0 | 万物智能的基础服务
  7. springcloud 熔断不生效_深入理解SpringCloud与微服务构建
  8. UVA - 1643 Angle and Squares (角度和正方形)(几何)
  9. 你的数仓函数结果不稳定,可能是属性指定错了
  10. Redhat(Linux)上的JBoss管理配置
  11. Ubuntu 12.10方便操作套件
  12. 数组最大子数组和(续)之动态规划
  13. BTP-2118 玩 GTA5
  14. GitHub上点击量破百万的宝藏级Spring,讲解的太到位了
  15. Scapy:send函数剖析(参数、返回值、应用)
  16. 微信做音乐相册html5,如何制作微信音乐相册 微信音乐相册制作软件的精品教程...
  17. inv在线计算机,INV3062A
  18. 低俗广告的“擦边球”为何有道、白云山都来打了?
  19. 前馈神经网络(FNN)
  20. python大数据工程师需要掌握哪些_大数据工程师 python

热门文章

  1. HDOJ1012 u Calculate e
  2. 北京可以备案什么域名
  3. linux中java 里面启动 重启 停止jar 的 shell
  4. 国产手机:跨出去之路
  5. 会写helloworld,不等于入门
  6. 一个小学教师建站的不惑与困惑
  7. (android实战)第三方应用反编译并修改UI信息后,重新编译
  8. .NET 4.0的犄角旮旯
  9. OA、CRM、进销存集成了,美女也不再愁了
  10. HttpModule httpHandle 执行顺序