c++空类实例大小不是0原因

转载:http://blog.csdn.net/hitblue/article/details/3726754

初学者在学习面向对象的程序设计语言时,或多或少的都些疑问,我们写的代码与最终生编译成的代码却 大相径庭,我们并不知道编译器在后台做了什么工作.这些都是由于我们仅停留在语言层的原因,所谓语言层就是教会我们一些基本的语法法则,但不会告诉我们为什么这么做?今天和大家谈的一点感悟就是我在学习编程过程中的一点经验,是编译器这方面的一个具体功能.

首先:我们要知道什么是类的实例化,所谓类的实例化就是在内存中分配一块地址.

那我们先看看一个例子:

#include<iostream>
using namespace std;
class a {};
class b{};
class c:public a{virtual void fun()=0;
};
class d:public b,public c{};
int main()
{cout<<"sizeof(a)"<<sizeof(a)<<endl;cout<<"sizeof(b)"<<sizeof(b)<<endl;cout<<"sizeof(c)"<<sizeof(c)<<endl;cout<<"sizeof(d)"<<sizeof(d)<<endl;return  0;}

程序执行的输出结果为:

sizeof(a)1
sizeof(b)1
sizeof(c)4
sizeof(d)8
请按任意键继续. . .

为什么会出现这种结果呢?初学者肯定会很烦恼是吗?类a,b明明是空类,它的大小应该为为0,为什么 编译器输出的结果为1呢?这就是我们刚才所说的实例化的原因(空类同样可以被实例化),每个实例在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址.所以a,b的大小为1.

而类c是由类a派生而来,它里面有一个纯虚函数,由于有虚函数的原因,有一个指向虚函数的指针(vptr),在32位的系统分配给指针的大小为4个字节,所以最后得到c类的大小为4.

类d的大小更让初学者疑惑吧,类d是由类b,c派生迩来的,它的大小应该为二者之和5,为什么却是8  呢?这是因为为了提高实例在内存中的存取效率.类的大小往往被调整到系统的整数倍.并采取就近的法则,里哪个最近的倍数,就是该类的大小,所以类d的大小为8个字节.

当然在不同的编译器上得到的结果可能不同,但是这个实验告诉我们初学者,不管类是否为空类,均可被实例化(空类也可被实例化),每个被实例都有一个独一无二的地址.

我所用的编译器为vs2008.

下面我们再看一个例子.

#include<iostream>
using namespace std;
class a{
private: int data;
};class b{ 
private:int data;static int data1;
};
int b::data1=0;
void main(){cout<<"sizeof(a)="<<sizeof(a)<<endl;cout<<"sizeof(b)="<<sizeof(b)<<endl;
}

程序执行输出结果为:

sizeof(a)=4
sizeof(b)=4
请按任意键继续. . .


为什么类b多了一个数据成员,却大小和类a的大小相同呢?因为:类b的静态数据成员被编译器放在程序的一个global  data members中,它是类的一个数据成员.但是它不影响类的大小,不管这个类实际产生 了多少实例,还是派生了多少新的类,静态成员数据在类中永远只有一个实体存在,而类的非静态数据成员只有被实例化的时候,他们才存在.但是类的静态数据成员一旦被声明,无论类是否被实例化,它都已存在.可以这么说,类的静态数据成员是一种特殊的全局变量.

所以a,b的大小相同.

下面我们看一个有构造函数,和析构函数的类的大小,它又是多大呢?

<p style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; line-height: 26px;">
</p><pre name="code" class="cpp">#include<iostream>
using namespace std;
class A{
public :A(int a){x=a;}void f(int x){cout<<x<<endl;}~A(){}private:int x;int g;
};
class B{
public:
private:int  data;int data2;static int xs;
};
int B::xs=0;
void  main(){A s(10);s.f(10);cout<<"sozeof(a)"<<sizeof(A)<<endl;cout<<"sizeof(b)"<<sizeof(B)<<endl;
}

执行结果为:

10
sozeof(a)8
sizeof(b)8
请按任意键继续. . .


 

它们的结果均相同,可以看出类的大小与它当中的构造函数,析构函数,以及其他的成员函数无关,只与它当中的成员数据有关

从以上的几个例子不难发现类的大小:

1.为类的非静态成员数据的类型大小之和.

2.有编译器额外加入的成员变量的大小,用来支持语言的某些特性(如:指向虚函数的指针).

3.为了优化存取效率,进行的边缘调整.

4 与类中的构造函数,析构函数以及其他的成员函数无关.


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

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

相关文章

为什么Docker是云计算必然的现在和未来

Docker所代表的Container技术&#xff0c;是对内核的Cgroups、namespace等内容的使用.Linux Containerlxc借助BootZdocker可以实现在Mac和Windows上运行CGroups限制容器的资源使用Namespace机制&#xff0c;实现荣期间的隔离chroot,文件系统的隔离Linux内核提供的限制&#xff…

linux桌面环境 mac os,在Windows或Linux桌面上使用Mac OS Dashboard Widget | MOS86

Windows Vista中引入了Gadgets&#xff0c;并在Windows 7中继续使用。它们允许您从最新的新闻更新到月球的各个阶段查看各种信息&#xff0c;并在桌面上使用一些有用的实用程序。我们以前写过一个程序&#xff0c;允许您在Windows XP中使用Windows 7风格的小工具和一些实用程序…

spark 笔记 16: BlockManager

spark 笔记 16&#xff1a; BlockManager 先看一下原理性的文章&#xff1a;http://jerryshao.me/architecture/2013/10/08/spark-storage-module-analysis/ &#xff0c;http://jerryshao.me/architecture/2013/10/08/spark-storage-module-analysis/ , 另外&#xff0c;spar…

python的异常处理

python的try语句有两种风格 一&#xff1a;种是处理异常&#xff08;try/except/else&#xff09; 二&#xff1a;种是无论是否发生异常都将执行最后的代码&#xff08;try/finally&#xff09; try/except/else风格 try: <语句> #运行别的代码 except <名字>&…

解决SQL单用户模式不能转为多用户模式

数据库CS 转为单用户模式后&#xff0c;却不能访问属性&#xff0c;一直想不通&#xff0c;但毕竟是测试用的&#xff0c;也就没放心上。网上找到段代码可以恢复多用户模式。却还是不能解决不能访问单用户属性的问题。USE master;GoDECLARE SQL VARCHAR(MAX);SET SQLSELECT SQL…

C++ stringstream介绍,使用方法与例子

C引入了ostringstream、istringstream、stringstream这三个类&#xff0c;要使用他们创建对象就必须包含sstream.h头文件。   istringstream类用于执行C风格的串流的输入操作。 ostringstream类用于执行C风格的串流的输出操作。 strstream类同时可以支持C风格的串流的输入…

xp下添加linux启动,如何在windows xp系统下安装linux???

我刚刚想开始学linux&#xff0c;请教如何安装&#xff01;|我今天才安装了Redhat 9.0。LINUX不可能在WINDOWS下安装。比较简单的方法是先在XP下用PQMAGIC分好区boot ext3 100M , / ext3 6G , swap 内存1&#xff0d;2倍详细见www.linuxfans.org linux安装说明最后&#xf…

linux rar安装

描述&#xff1a;Linux默认自带ZIP压缩&#xff0c;最大支持4GB压缩&#xff0c;RAR的压缩比大于4GB. 流程&#xff1a;下载 》安装 》 使用 -------------------------------------------------- 下载 # wget http://www.rarsoft.com/rar/rarlinux-x64-5.2.1b1.tar.gz--16:01:…

hoj 2739 中国邮局问题

1 /*若原图的基图不连通,2 或者存在某个点的入度或出度为 0 则无解。3 统计所有点的入度出度之差 Di, 对于 Di > 0 的点,4 加边(s, i, Di, 0); 对于 Di < 0 的点加边(i, t, -Di,0);5 对原图中的每条边(i, j),6 在网络中加边(i, j, ∞, Dij),Dij 为边(i, j)的权值。7 求一…

R语言编程艺术(3)R语言编程基础

本文对应《R语言编程艺术》 第7章&#xff1a;R语言编程结构&#xff1b; 第9章&#xff1a;面向对象的编程&#xff1b; 第13章&#xff1a;调试 R语言编程结构 控制语句&#xff1a; 循环&#xff1a; for (n in x) { } while (condition) { } repeat { }另外break也可以用在…

用C++流成员函数put输出单个字符

转载&#xff1a;http://c.biancheng.net/cpp/biancheng/view/254.html 在程序中一般用cout和插入运算符“<<”实现输出&#xff0c;cout流在内存中有相应的缓冲区。有时用户还有特殊的输出要求&#xff0c;例如只输出一个字符。ostream类除了提供上面介绍过的用于格式控…

linux 扩充db2表空间,如何扩充db2的表空间、加容器等表空间维护操作

db2 "alter tablespace GJDATA resize (FILE /backup/GJDATA32K45G)"db2 "alter tablespace GJIDX resize (FILE /backup/GJIDX32K45G)"容器路径 db2 list tablespace containers for8容器大小 db2pd -d uibsch -tablespaces降低容器空间 resize 增加容器…

CheckBox控件

前台代码&#xff1a; 1 <asp:CheckBox ID"CheckBox1" runat"server" Text "苹果"/> 2 <asp:CheckBox ID"CheckBox2" runat"server" Text "柠檬"/> 3 <asp:CheckBox ID"CheckBox3" runa…

.NET垃圾回收笔记

名词 垃圾收集目标 ephemeral GC发生在Gen 0 和Gen 1 的垃圾收集 Full GC发生Gen 2 及以上的Gen与LOH的垃圾收集 垃圾收集模式 工作站模式GC直接发生在内存分配的线程&#xff08;也是当前的工作托管线程&#xff09;上 服务器模式每个CPU核都有一个自己独立的GC线程与托管堆 垃…

go.js中的图标(icons)的使用

2019独角兽企业重金招聘Python工程师标准>>> 1、图标库下载&#xff1a; 将icons引入&#xff1a;http://gojs.net/latest/samples/icons.js 2、样式演示 地址&#xff1a;http://gojs.net/latest/samples/icons.html 转载于:https://my.oschina.net/u/2391658/blog…

Pygame - Python游戏编程入门(1)

前言 在上一篇中&#xff0c;我们初步熟悉了pygame的控制流程&#xff0c;但这对于一个游戏而言是远远不够的。所以在这一篇中&#xff0c;我们的任务是添加一架飞机&#xff08;玩家&#xff09;&#xff0c;并且能够控制它进行移动&#xff0c;这样我们就又离目标进了一步了~…

C++字符输入getchar()和字符输出putchar()

转载&#xff1a;http://c.biancheng.net/cpp/biancheng/view/117.html C还保留了C语言中用于输入和输出单个字符的函数&#xff0c;使用很方便。其中最常用的有getchar函数和putchar函数。 putchar函数(字符输出函数) putchar函数的作用是向终端输出一个字符。例如&#xf…

linux实现shell,linux

4.5Mhttp://www.starbase-929.net/media/Calibre%20Library/Ken%20O.%20Bartch/Linux%20Shell%20Scription%20With%20Bash%20(1778)/Linux%20Shell%20Scription%20With%20Bash%20-%20Ken%20O.%20Bartch.pdfstarbase-929.net全网免费4.0Mhttp://www.myaitcampus.net/elibrary/im…

AQS浅析

2019独角兽企业重金招聘Python工程师标准>>> AQS的原理浅析 本文是《Java特种兵》的样章&#xff0c;本书即将由工业出版社出版 AQS的全称为&#xff08;AbstractQueuedSynchronizer&#xff09;&#xff0c;这个类也是在java.util.concurrent.locks下面。这个类似乎…

str045漏洞提权linux,Linux运维知识之CVE-2016-5195 Dirtycow: Linux内核提权漏洞

本文主要向大家介Linux运维知识之CVE-2016-5195 Dirtycow&#xff1a; Linux内核提权漏洞绍了&#xff0c;通过具体的内容向大家展现&#xff0c;希望对大家学习Linux运维知识有所帮助。CVE-2016-5195 Dirtycow&#xff1a; Linux内核提权漏洞以下都是github上找的源码&#xf…