转自https://blog.csdn.net/zhengjihao/article/details/77825269

其中有的描述与实际GCC上执行的结果不符,不过其中的分析思路需要掌握。

以下是GCC的实际执行结果:

  1 #include <iostream>
  2 using namespace std;
  3
  4 int *pointer;
  5
  6 class NullCls {};
  7
  8 class NullVirtual {
  9 public:
 10     virtual void fun() {};
 11     virtual void fun2() {};
 12 };
 13
 14 class CSI {
 15 public:
 16     char b;
 17     short c;
 18     int a;
 19 };
 20
 21 class CIS {
 22 public:
 23     char b;
 24     int a;
 25     short c;
 26 };
 27
 28 class CSV {
 29 public:
 30     char b;
 31     short c;
 32     virtual void fun() {};
 33 };
 34
 35 class CVS {
 36 public:
 37     char a;
 38     virtual void fun() {};
 39     short b;
 40 };
 41
 42 class StaticInt {
 43 public:
 44     char b;
 45     virtual void fun() {};
 46     static int c;  // 放在程序的global data members中
 47 };
 48
 49 class Method {
 50 public:
 51     void fun() {};
 52 };
 53
 54 class Parent {
 55 public:
 56     int c;
 57 };
 58
 59 class Son : public Parent {
 60 public:
 61     int b;
 62 };
 63
 64 class Parent2 {
 65 public:
 66     int a;
 67     char b;
 68 };
 69
 70 class Son2 : public Parent2 {
 71 public:
 72     char c;
 73 };
 74
 75 class A
 76 {
 77     virtual void fun() {}
 78 };
 79
 80 class B
 81 {
 82     virtual void fun2() {}
 83 };
 84
 85 class C : virtual public  A, virtual public B
 86 {
 87 public:
 88     virtual void fun3() {}
 89 };
 90
 91 class C2 : public A, public B
 92 {
 93 public:
 94     virtual void fun3() {}
 95 };
 96
 97 void size(string name, int s) {
 98     cout << name << "=" << s << endl;
 99 }
100
101 int main(){
102     size("pointer", sizeof(pointer));  // 8
103     size("NullCls", sizeof(NullCls));  // 1
104     size("NullVirtual", sizeof(NullVirtual));  // 8
105     size("CSI", sizeof(CSI));  // 8
106     size("CIS", sizeof(CIS));  // 12
107     size("CSV", sizeof(CSV));  // 16
108     size("CVS", sizeof(CVS));  // 16
109     size("StaticInt", sizeof(StaticInt));  // 16
110     size("Method", sizeof(Method));  // 1
111     size("Son", sizeof(Son));  // 8
112     size("Son2", sizeof(Son2));  // 12
113     size("C", sizeof(C));  // 16
114     size("C2", sizeof(C2));  // 16
115 }

《原文如下》

1空类

1 class A {};

大小为1。

类的实例化就是给每一个实例在内存中分配一块地址。空类被实例化时,会由编译器隐含的添加一个字节。所以空类的size为1。
2 虚函数

class A
{public:virtual void fun() {};virtual void fun2() {};
};

大小为4。

当C++类中有虚函数的时候,会有一个指向虚函数表(V-table)的指针,所有的虚函数都在这个表中。指针大小为4,所以size为4。

在来看如下代码:

class A
{public:char b;short c;int a;
};
class B
{public:char a;int c;short b;
};

考虑数据对齐,大小分别为 8 和 12。如果我们将int换成虚函数,会是什么结果呢?

class A
{
public:char b;short c;virtual void fun() {}
};
class B
{
public:char a;virtual void fun() {}short b;
};

大小分别为 8 8。 都是占4个字节,结果不一样。 这是因为,为了效率问题,编译器(gcc 和 微软)一般会把虚指针放在类的内存空间的最前面的位置,不管虚函数声明的位置。考虑对齐,大小都是 4 +1+1+2 = 8.

3 静态数据成员

class A
{
public:char b;virtual void fun() {};static int c;
};

大小为8。

静态数据成员被编译器放在程序的一个global data members中,它是类的一个数据成员,但不影响类的大小。不管这个类产生了多少个实例,还是派生了多少新的类,静态数据成员只有一个实例。静态数据成员,一旦被声明,就已经存在。 考虑到数据对齐, 最终是8字节。

4 普通成员函数

class A
{
public:void fun() {};
};

大小为1。

类的大小与构造函数,析构函数,普通成员函数无关。

5 普通单继承

class A
{int c;
};
class B : public A
{int a;
};

大小分别为4 和 8。 可以看到普通的继承就是基类的大小+派生类自身的大小。注意数据对齐。

注意:类的数据成员按其声明顺序加入内存,无访问权限无关,只看声明顺序。

class A
{int a;char b;
};
class C : public A
{public:char c;
};

上面这段代码,不同的编译器结果不同,VS的结果是 8 和 12, GCC是8 和 8。VS中 相当于

class C
{A a;char c;
};

A的大小为8,对齐值为4, 则考虑总体对齐 8 + 1 + 3(padding) = 12。

GCC 则是

class C
{int a;char b;char c;
};

结果为 4 + 1 + 1 + 2 = 8。【与实际执行有出入】

6 含虚函数的单继承

class A
{virtual void fun () {}
};
class C : public A
{
public:virtual void fun2() {}
};

大小分别为4 和 4。派生类继承了基类的虚指针,所以大小为4。

7 虚单继承

class A
{virtual void fun () {}
};class C : virtual public A
{
public:virtual void fun2() {}
};

这段代码,VS和gcc结果不一样。VS为 4 和 12。 gcc为4 和4。

8 普通多继承

class A
{int a;char b;
};class B
{char b;
};
class C : public A, public B
{
public:char c;
};

VS:8 1 12

GCC:8 1 8
VS中相当于把A B当做整体看待, GCC则拆分整合。

9 虚函数多继承

class A
{virtual void fun() {}
};class B
{virtual void fun2() {}
};
class C : public A, public B
{
public:virtual void fun3() {}
};

结果为 4 4 8。分析:类A一个虚函数表,类B一个虚函数表,类C继承了两个虚函数表,并把自己的虚函数写在了继承顺序中第一个虚函数表中。

10 虚继承

class A
{virtual void fun() {}
};class B
{virtual void fun2() {}
};
class C : virtual public A, virtual public B
{
public:virtual void fun3() {}
};

GCC: 4 4 8   VS:4 4 16

转载于:https://www.cnblogs.com/qxxnxxFight/p/11134143.html

【转】C++类的sizeof大小相关推荐

  1. 类的sizeof大小和C语言中各种数据类型的长度

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

  2. 【转】求一个类的sizeof应考虑的问题

    源地址 昨天面试,面试官让我说一说求一个类的sizeof应该考虑的问题,心想,太好了,之前sizeof可是做了不少功夫,就说了类的非静态.非全局成员,如果有虚函数就要加上一个指向虚表的指针,4字节大小 ...

  3. C++实现一个有理数类,包括大小比较,有理数的加减乘除。测试你的类。

    //实现一个有理数类,包括大小比较,有理数的加减乘除.测试你的类. #include <iostream> #include <stdlib.h>class Rational ...

  4. itextpdf如何不使用font类设置字体大小

    iTextPdf不使用Font类设置字体大小可以使用setFontSize()方法来设置字体大小.例如: document.add(new Paragraph("这是一个段落"). ...

  5. 计算类class的sizeof大小

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

  6. 【C】sizeof(空结构体/空类)的大小

    sizeof(空类/空结构体) = 1: #include <iostream> using namespace std; // 空类 class ClassA { }; // 继承空类的 ...

  7. 空类,虚函数类,虚继承类的空间大小

    //此代码在32位win下运行成功 #include<iostream> using namespace std; class A//A是空类,编译器会用一个char类型标记这个类,大小为 ...

  8. 带虚函数的类的sizeof分析

    一个类中若有虚函数,(不论是自己的虚函数,还是继承而来的),那么类中就有一个成员变量:虚函数指针.虚函数指针占4字节 直接看例子: class base1{ private:int a; public ...

  9. c++ 类的sizeof

    sizeof()是c++的运算符,返回变量或者类型占用的字节数.如sizeof(int) 为4,sizeof(char) 为1. 那么类大小呢,如 1 class A { 2 char a; 3 sh ...

最新文章

  1. .net通过一般处理程序模拟用户控件数据保持、Ispostback 【第二版将html与ashx文件分开】...
  2. opencv进阶学习笔记14:分水岭算法 实现图像分割
  3. lesson1-python3运算符
  4. Tomcat 7上具有RESTeasy JAX-RS的RESTful Web服务-Eclipse和Maven项目
  5. 小爱同学app安卓版_小爱课程表3.0全新升级 课表倒入更简单所有手机能用
  6. 2020年11月 Oracle WebLogic 高危预警:CVE-2020-14750 无需认证攻击
  7. 美创意 -vue 组件的网站
  8. 6 个步骤,搞定 AI 车牌识别器!(附详细分析)
  9. java md5方法 for Android
  10. 计算机网络数据传输率的基本单位是,计算机网络中,数据的传输速度常用的单位是什么...
  11. 如何让微信号开通检测软件替你顶起一片天?
  12. 华宇(大连)笔试-20190620
  13. 沭阳学爬虫10高效存储MongoDB
  14. JavaWeb的jsp文件EL表达式简写优先级
  15. 什么是Type-c降噪耳机?type-c接口耳机降噪方案
  16. QSlider美化规则
  17. 优达学城无人驾驶工程师——P4车道线检测功能
  18. 为什么说Vue是渐进式框架?
  19. 电脑微信linux安装程序,Ubuntu安装Linux网页版微信
  20. bedtools从剪切位点两边提取序列

热门文章

  1. cognos报表导出excel_有了这个报表工具,一键生成自定义的各种报表,还可以导出Excel...
  2. python self 值自动改变_Python,为什么传递和更改带有外部函数的类selfvariable用于操作iterable而不是变量...
  3. 的mvc_简述PHP网站开发的MVC模式
  4. Java常用设计模式————抽象工厂模式
  5. 2019 d serv 激活_化疗过程中肌肉减少症的发生机制及维生素D、ω-3脂肪酸的作用...
  6. 计算机组成原理r型指令logisim实现_第一章 计算机体系结构
  7. python之if经典语句_Python之if语句、字典
  8. 震惊! Rightmost Digit 快速幂解决
  9. php李捷,【问题解答】蝶泳手外划的作用
  10. java swing linux_Linux下关于解决JavaSwing中文乱码的情况