1 sizeof一个空类

class A { };cout<<sizeof(A)<<endl;//1

注:class A是一个空类型,它的实例不包含任何信息,本来求sizeof应该是0。

但当我们声明该类型的实例的时候,它必须在内存中占有一定的空间,否则无法使用这些实例。

至于占用多少内存,由编译器决定。Visual Studio 2008中每个空类型的实例占用一个byte的空间。

2 sizeof一个带有构造和析构函数的类

class B{public:B() {}~B() {}};cout<<szieof(B)<<endl;//1

  

注:class B在class A的基础上添加了构造函数和析构函数。

由于构造函数和析构函数的调用与类型的实例无关(调用它们只需要知道函数地址即可),在它的实例中不需要增加任何信息。

所以sizeof(B)和sizeof(A)一样,在Visual Studio 2008中都是1。

3 sizeof一个带有虚函数的类

class C{public:C() {}virtual ~C() {}};cout<<sizeof(C)<<endl;//4

  

注:class C在class B的基础上把析构函数标注为虚拟函数。C++的编译器一旦发现一个类型中有虚拟函数,

就会为该类型生成虚函数表,并在该类型的每一个实例中添加一个指向虚函数表的指针。

在32位的机器上,一个指针占4个字节的空间,因此sizeof(C)是4。

C++标准规定类的大小不为0,空类的大小为1,当类不包含虚函数和非静态数据成员时,其对象大小也为1。

如果在类中声明了虚函数(不管是1个还是多个),那么在实例化对象时,编译器会自动在对象里安插一个指针指向虚函数表VTable,

在32位机器上,一个对象会增加4个字节来存储此指针,它是实现面向对象中多态的关键。而虚函数本身和其他成员函数一样,是不占用对象的空间的。

4 sizeof一个带有成员变量的类

class D {char ch;void func() { }};class E {char ch1; //占用1字节char ch2; //占用1字节virtual void func() { }};
class F {int in;virtual void func() { }};cout << "D的大小"<< sizeof(D) << endl;//1
cout << "E的大小" << sizeof(E) << endl;//8
cout << "F的大小" << sizeof(E) << endl;//8

 注:类和结构体一样,需要考虑数据对齐和补齐规则

5 sizeof简单继承类

class COneMember{public:COneMember(int iValue = 0){m_iOne = iValue;};private:int m_iOne;};内存结构:00 00 00 00 //m_iOneclass CTwoMember:public COneMember{private:int m_iTwo;};内存结构:00 00 00 00 //m_iOneCC CC CC CC //m_iTwo注:子类成员接在父类成员之后class CThreemember:public CTwoMember{public:CThreemember(int iValue=10) {m_iThree = iValue;};private:int m_iThree;};
内存结构:
00 00 00 00 //m_iOneCC CC CC CC //m_iTwo0A 00 00 00 //m_iThree注:孙类成员接在子类之后,再再继承就依此类推了。cout<<sizeof(COneMember)<<endl;//4
cout<<sizeof(CTwoMember)<<endl;//8
cout<<sizeof(CThreeeMember)<<endl;//12

 

6 sizeof多重继承类

class ClassA{public:ClassA(int iValue=1){m_iA = iValue;};private:int m_iA;};class ClassB{public:ClassB(int iValue=2){m_iB = iValue;};private:int m_iB;};class ClassC{public:ClassC(int iValue=3){m_iC = iValue;};private:int m_iC;};class CComplex :public ClassA, public ClassB, public ClassC{public:CComplex(int iValue=4){m_iComplex = iValue;};private:int m_iComplex;};内存结构:
01 00 00 00  //A02 00 00 00  //B03 00 00 00  //C04 00 00 00  //Complex注:也是父类成员先出现在前边,我想这都足够好理解。cout<<sizeof(CComplex )<<endl;//16

  

7 sizeof 虚继承的类

class CTwoMember:virtual public COneMember{private:int m_iTwo;};内存结构:E8 2F 42 00 //指针,指向一个关于偏移量的数组,且称之虚基类偏移量表指针CC CC CC CC // m_iTwo00 00 00 00 // m_iOne(虚基类数据成员)长度:12

注:virtual让长度增加了4,其实是多了一个指针。

  

8 sizeof一个闭合虚继承类

内存结构:

14 30 42 00 //ClassB的虚基类偏移量表指针

02 00 00 00 //m_iB

C4 2F 42 00 //ClassC的虚基类偏移量表指针

03 00 00 00 //m_iC

04 00 00 00 //m_iComplex

01 00 00 00 //m_iA

长度:24

注:虚基类的成员m_iA只出现了一次,而且是在最后边。虚继承利用一个“虚基类偏移量表指针”来使得虚基类即使被重复继承也只会出现一次。

9 sizeof一个带有static数据成员的类

class CStaticNull{public:CStaticNull(){printf("Construct/n");}~CStaticNull(){printf("Desctruct/n");}static void Foo(){printf("Foo/n");}static int m_iValue;};内存结构:和空类相同
长度:1
注:static成员不会占用类的大小,static成员的存在区域为静态区,可认为它们是“全局”的,只是不提供全局的访问而已,这跟C的static其实没什么区别。

  

10 带有一个虚函数的空类

class CVirtualNull{public:CVirtualNull(){printf("Construct/n");}~CVirtualNull(){printf("Desctruct/n");}virtual void Foo(){printf("Foo/n");}};内存结构:
00 31 42 00 //指向虚函数表的指针(虚函数表后面简称“虚表”)00423100:(虚表)
41 10 40 00 //指向虚函数Foo的指针00401041:
E9 78 02 00 00 E9 C3 03 … //函数Foo的内容(看不懂)长度:4
注:虚函数的类长度就增加了4,这个4其实就是个指针,指向虚函数表的指针,上面这个例子中虚表只有一个函数指针,值就是“0x00401041”,指向的这个地址就是函数的入口了

  

11 sizeof一个继承带虚函数的类

class CVirtualDerived : public CVirtualNull{public:CVirtualDerived(){m_iVD=0xFF;};~CVirtualDerived(){};private:int m_iVD;};长度:8
内存结构:
3C 50 42 00 //虚表指针
FF 00 00 00 //m_iVD0042503C:(虚表)
23 10 40 00 //指向虚函数Foo的指针,如果这时候创建一个CVirtualNull对象,会发现它的        虚表的内容跟这个一样注:由于父类带了虚函数,子类就算没有显式声明虚函数,虚表还是存在的,虚表存放的位置跟父类不同,但内容是同的,也就是对父类虚表的复制。

  

12 sizeof子类带虚函数,基类带虚函数

class CVirtualDerived: public CVirtualNull{public:CVirtualDerived(){m_iVD=0xFF;};~CVirtualDerived(){};virtual void Foo2(){printf("Foo2/n");};private:int m_iVD;};内存结构:
24 61 42 00 //虚表指针
FF 00 00 00 //m_iVD00426124:(虚表)
23 10 40 00
50 10 40 00长度:8
注:虚表还是只有一张,不会因为增加了新的虚函数而多出另一张来,新的虚函数的指针将添加在复制了的虚表的后面。

  

转载于:https://www.cnblogs.com/LuckCoder/p/10452766.html

sizeof计算类的大小相关推荐

  1. c++面试常用知识(sizeof计算类的大小,虚拟继承,重载,隐藏,覆盖)

    一. sizeof计算结构体 注:本机机器字长为64位 1.最普通的类和普通的继承 #include<iostream> using namespace std;class Parent{ ...

  2. 使用sizeof计算类的大小

    类的sizeof大小一般是类中的所有成员的sizeof大小之和,这个就不用多说. 不过有两点需要注意:1)当类中含有虚成员函数的时候,例如: class B { float a; public: vi ...

  3. 1.使用sizeof计算类的大小

    类的sizeof大小一般是类中的所有成员的sizeof大小之和. 不过有两点需要注意: 1)当类中含有虚成员函数的时候,例如: class B { float a; public: virtual v ...

  4. sizeof计算类大小

    类的sizeof大小一般是类中的所有成员的sizeof大小之和,这个就不用多说. 不过有两点需要注意:1)当类中含有虚成员函数的时候,例如: class B { float a; public: vi ...

  5. 使用sizeof()计算结构体大小

    下面代码的输出结果是: #include <iostream> using namespace std; #pragma pack(4) struct T{ char a; short b ...

  6. 3-2:类与对象上篇——类的对象模型和计算类的大小以及this指针问题

    文章目录 一:类对象模型 (1)如何计算类对象的大小 (2)类对象的存储方式 二:this指针 (1)一个问题 (2)this指针 (3)this指针存在哪里? 一:类对象模型 (1)如何计算类对象的 ...

  7. 计算类class的sizeof大小

    1.实例1如下: class A{};class B{char ch;int x;};class C{public:void Print(void){}};class D{public:virtual ...

  8. sizeof()计算结构体的大小

    原文链接:sizeof()计算结构体的大小_海月汐辰-CSDN博客_结构体的sizeof怎么计算 简要说明:结构体成员按照定义时的顺序依次存储在连续的内存空间,但是结构体的大小并不是简单的把所有成员大 ...

  9. sizeof()来求一个类的大小

    基本概念 一个类的实例化对象所占空间的大小? 注意不要说类的大小,是类的对象的大小. 首先,类的大小是什么?确切的说,类只是一个类型定义,它是没有大小可言的. 用sizeof运算符对一个类型名操作,得 ...

最新文章

  1. R语言ggplot2可视化使用ggplot2包patchwork包在可视化结果(右上角)中插入logo图片
  2. java io文件流序列化_Java——Properties集合,Object序列化流与反序列化流,打印流,commons-IO文件工具类...
  3. JAVA学习:maven开发环境快速搭建How to download J2EE API (javaee.jar) from Maven
  4. Android之通过ContentProvider实现两个app(进程间)间通信以及函数调用
  5. fork()调用使子进程先于父进程被调度
  6. toj 4609 Internal Rate of Return
  7. 农信银高莉:农信科技共享计划
  8. java 蓝桥杯算法训练 数字三角形(题解)
  9. html调用rpst 源码_parseHTML 函数源码解析(四) AST 基本形成
  10. 手工制作totem播放器的播放列表
  11. 虫儿飞简谱用计算机,乐曲简谱(虫儿飞简谱)
  12. dma子系统 dmac
  13. Redis数据库简介
  14. 加工生产调度(流水作业调度问题)——Johnson算法应用
  15. 笔记本电脑开启热点后电脑无法上网问题——亲测可行【06-17】
  16. 函数式编程另类指南 (zz)
  17. Oracle分区表的使用
  18. python——difflib内置模块之文本对比
  19. 佳能相机断电DAT文件有大小无法播放的修复方法
  20. php输入中文就乱码,在php图片中输入中文文字解决乱码

热门文章

  1. MySql按字段分组取最大值记录
  2. Device Tree(三):代码分析【转】
  3. openssl创建CA、申请证书及其给web服务颁发证书
  4. Mozilla网站安全分析工具Observatory已发布
  5. 模式识别之Shape Context---利用Shape Context进行形状识别
  6. 一款非常好用的Linux下的C/C++ IDE
  7. 由键盘下陷引起的奇怪事件
  8. if you want to buy something
  9. C# 类型运算符重载在类继承中的调用测试
  10. NOJ --138 找球号(二)