【转】C++类的sizeof大小

转自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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/569241.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

shiro扩展获得用户登录类型并提供cookie的方式记住用户密码

在最近的项目中要实现一个需求&#xff1a;“同时让两种类型的用户进行登录&#xff0c;登录后如果用户勾选了记住密码就要生成cookie来记录用户的密码和用户名”。本人做安全认证的时候一直在使用shiro&#xff0c;所以就想到在shiro的基础上进行一些扩展来满足需求。 shiro自…

ueditor跨域上传图片文件(基于jsp框架、tomcat)

额&#xff0c;好久没有用到ueditor了&#xff0c;因为现在的相关工作很少涉及到富文本编辑&#xff1b;最近临时带了一个项目&#xff0c;里面要用到富文本编辑器&#xff0c;而且文件要统一上传到文件服务器上保存&#xff1b;应为以前用过ueditor就试着在网上着一些跨域保存…

JavaWeb-RESTful_用SpringMVC开发RESTful

RESTful简介 一种软件架构风格、设计风格&#xff0c;而不是标准&#xff0c;只是提供了一组设计原则和约束条件。 它主要用于客户端和服务器交互类的软件。 基于这个风格设计的软件可以更简洁&#xff0c;更有层次&#xff0c;更易于实现缓存等机制。 RESTful可以理解为一种编…

在storm中使用流

storm是一个强大的流式计算框架&#xff0c;单流的storm在使用中非常普遍&#xff0c;而同时storm也提供对多个流的支持&#xff1b;通过定义多个流&#xff0c;用户可以进一步的把数据发放到不同的流中进行处理。 代码如下&#xff1a; 一、 定义多个流的spout public class…

精选Pycharm里6大神器插件

http://www.sohu.com/a/306693644_752099 上次写了一篇关于Sublime的精品插件推荐&#xff0c;有小伙伴提议再来一篇Pycharm的主题。相比Sublime&#xff0c;Pycharm要强大许多&#xff0c;而且是专为python设计的集成开发环境&#xff0c;所以无论是自身功能、环境配置还是使用…

在storm中使用定时保存

在storm中使用实时保存会对性能带来很大的考验&#xff0c;所以在很多场景中还是使用定时保存&#xff1b;而且storm自带了定时功能&#xff0c;使用方式如下&#xff1a; 首先在topo中的config中定义一个通信时间&#xff0c;定义方式如下&#xff1a; conf.put(Config.TOPOLO…

数字信号处理实验(一)——DTFT

一、离散序列傅里叶变化——DTFT 1、DTFT公式 2、Matlab算法实现 function[X]dtft(x,n,w,flag)%计算离散时间付里叶变换 %[X]dtft(x,n,w) %X在w频率点上的DTFT数组 %xn点有限长度序列 %n样本位置向量 %w频率点位置向量X x * (exp(-j).^(n * w));3、DTFT一些画图代码 function …

修改hadoop中yarn的webui中显示的任务时间为中国时间

在${HADOOP_HOME}\share\hadoop\yarn目录下找到hadoop-yarn-common-x.x.x.jar&#xff0c;然后用winRAR打开&#xff1b; 打开以后结构如下&#xff1a; 进入webapps/static/目录&#xff0c;然后修改yarn.dt.plugins.js&#xff1b;做出如下修改&#xff1a; &#xff08;1&a…

一条语句复制整个目录《转》

使用的是 Delphi 2010 下 IOUtils 单元的 TDirectory.Copy 函数: 1 uses IOUtils; 2 3 procedure TForm1.Button1Click(Sender: TObject); 4 const 5 SourceDir C:\Temp\Folder1; { 源文件夹必须存在 } 6 DestDir C:\Temp\Folder2; { 如果目标文件夹不存在, 程序会自动…

设计模式与重构汇总

面向对象的基本原则&#xff1a;单一原则&#xff1a;引起一个类发生变化的原因只有一个 开放封闭原则&#xff1a;对于类的修改是封闭的&#xff0c;而对于类的扩展是开放的 依赖倒置原则&#xff1a;高层不依赖于底层&#xff0c;都应该依赖与抽象&#xff1b;抽象不依赖于…

转 最小凸包算法(Convex Hull)(1)-Graham扫描法 -计算几何-算法导论

原文地址&#xff1a;http://blog.csdn.net/suwei19870312/article/details/542281 基本问题&#xff1a; 平面上有n个点p1,p2, ..., pn, 要求求出一个面积最小的凸多边形&#xff0c;使得这个多边形包含所有平面上的点。 根据算法导论上提供的两个方法做一些介绍&#xff1a; …

Trident API 概览

Trident API 概览 在网上看到了很多有TRIDENT相关API的翻译&#xff0c;看来看去&#xff0c;总觉得没有说清楚很多东西&#xff0c;所以自己结合使用的经验翻译了一篇出来&#xff1b;翻译完以后&#xff0c;也发现 在自己的翻译中也有很多地方是表达不清楚的不过多少感觉有些…

poj 2406 还是KMP的简单应用

记住KMP是多计算一位的。其中next[i]为不为自身的最大首尾重复子串长度。 位移ji-next[i]可以看作是构成字符串s的字串&#xff08;如果i%j0&#xff0c;存在这样的构成&#xff09;&#xff0c;相应的重复次数也就是n/d。 a b c d * next:-1 0 0 0 0 这时ji-next[i]; …

Trident State译文

Trident State 译文 Trident针对状态化的数据源的读写进行了一流的分装。State可以包含在拓扑中-例如&#xff0c;保存在内存中&#xff0c;有HDFS提供备份-也可以保存在一个外部的数据库中&#xff0c;像Memcached和Cassandra。针对以上的所有情况&#xff0c;Trident的API都…

远程访问数据库查询数据量一大就Hang

最近刚为客户升级了一套Oracle Database&#xff0c;一切进展顺利&#xff0c;眼看就要顺利验收时&#xff0c;发现有部分客户端软件连接新版本数据库时会Hang&#xff0c;问题非常诡异。 系统环境如下 升级前的环境OS:Windows Server 2003 DB:Windows Database Enterprise Edi…

storm-hbase jar包中的bolt节点源码解析

一段时间内&#xff0c;大家都是自己在storm的节点中实现对hbase的操作&#xff0c;不管是普通的topo还是在trident中都是这样&#xff1b;不知道从那个版本起&#xff0c;在storm的压缩包中就多出了好几个jar包&#xff0c;把针对habse&#xff0c;mysql&#xff0c;mongodb等…

软件之道:软件开发争议问题剖析

软件之道&#xff1a;软件开发争议问题剖析 基本信息 原书名&#xff1a; Making Software 原出版社&#xff1a; OReilly 作者&#xff1a; (美)Andy Oram Greg Wilson 译者&#xff1a; 鲍央舟 张玳 沈欢星丛书名&#xff1a; 图灵程序设计丛书出版社&#xff1a;人民邮…

如何理解矩阵

线性代数课程&#xff0c;无论你从行列式入手还是直接从矩阵入手&#xff0c;从一开始就充斥着莫名其妙。比如说&#xff0c;在全国一般工科院系教学中应用最广泛的同济线性代数教材&#xff08;现在到了第四版&#xff09;&#xff0c;一上来就介绍逆序数这个“前无古人&#…

对于泛型的理解

如果希望构建一个集合容器&#xff0c;会用到ArrayList array new ArrayList(); ArrayList有几个缺点&#xff1a;1 无法保证容器中的类型安全&#xff08;类型一致问题&#xff09; 2 存进arralist的数据&#xff0c;CIL会自动进行装箱&#xff0c;也就是保存进ArrayList中的…

交通灯管理系统

题目需求&#xff1a; 模拟实现十字路口的交通灯管理系统逻辑&#xff0c;具体需求如下&#xff1a; 1、异步随机生成按照各个路线行驶的车辆。 例如&#xff1a; 由南向而来去往北向的车辆 ---- 直行车辆 由西向而来去往南向的车辆 ---- 右转车辆 由东向…