C++类的存储(部分可用与c的结构体)
c++中最重要的就是类,那么给你一个类的对象,你知道它在内存中如何存储的吗?它占内存中多少个字节?
首先确定类的构成:
1,数据成员:可以是内置类型,类类型。
2,函数成员:虚函数,非虚函数
1)数据成员
内置类型对齐原则
内置类型就是常用的:char,short,long,int,float,double.
这些内置类型在类的对象中对齐方式,字节为单位(在c中结构体也是一样的)
char 1
short 2
long 4
int 4
float 4
fouble 8
类类型对齐原则(c中就是结构体对齐原则)
取类中最长的数据成员作为对齐原则。例如,类中最长为double,那么就是8个字节。
2)函数成员
函数成员是不占用内存中类的对象的字节。为什么呢,你可以这样理解,c++中为了兼容c也允许struct作为类的声明。在c中struct是用来声明结构体类型的,只不过c中的结构体没有函数成员。
同样c++中允许的函数成员,只不过是类给函数提供了一个作用域。
一个对象调用函数的时候,可以等价为普通函数的调用
例如:
struct A
{
void f(){cout<<x<<endl;};
int x;
};
A a;
a.f();
a.f()等价于调用f(&a);类中的成员函数(static成员函数除外)形参中都有个隐含的this指针,它指向类对象本身。
当对象a调用f()的时候,它会把a的地址传给this指针,所以f()就等价执行
f(const A* this)
{
cout<<this->x<<endl;
}
所以对象中并不需要保存函数成员。
下面举个例子说明类对象的字节数
1,
class A
{
char c;
int i;
};
A a;
这对象a的内存大小sizeof(a)=8(字节为单位)
解释下:
c放在起始位置0,占1个字节。
i是int要4字节对齐,所以前面要空3字节。它要从位置4开始存储,占4,5,6,7四个位置。
最后类要按照他最长的数据成员对齐,就是i也就是4字节对齐.因为已经占用了8个字节,8是对齐4的,所以不用额外增加字节数了。最后sizeof(a)=8。
2,
class B
{
doube d;
char c;
A a;//1中的类类型A
};
B b;
这对象b的内存大小sizeof(b)=24(字节为单位)
解释:
d放在起始位置0到7,占8个字节。
c是char要1字节对齐,所以放在位置8,占1个字节。
b是类类型,在1中可以知道它是8字节对齐的,所以前面要空7个字节,它从位置16开始存储,一直到23,占8个字节。
最后类要按照他最长的数据成员对齐,就是d也就是8字节对齐,因为已经占用了24个字节,24是对齐8的,所以不用额外增加字节数了。最后sizeof(a)=24。
3,
class c
{
char c;
int i1;
double d;
int i2;
};
C c;
你知道sizeof(c)=多少吗? 答案:24.不解释了~。(注意这个最后需要额外增加空间来对齐类)
上面讲的,你同样可以使用c中的结构体类型变量的字节数计算。
下面说下特殊的,就是c中没有的。
1,类中有虚函数的时候
我们在一开始的时候,就说了成员函数中有虚函数。c++为了处理多态,所以引入虚函数,在一个类对象存储空间中,第一个位置需要4个字节来存储一个指针。这个指针是指向改类的虚函数表的。也就是这个指针的值就是改类的虚函数表的地址。所以就比上面说的多了4个字节。
例如:
class D
{
public:
virtual void f(){};
double d;
}
D d;
sizeof(d)=16;
2,派生类内存大小
例如:
class E:D
{
int d0;
char c;
int d1;
};
E e;
sizeof(e)=32;
解释:
基类中有虚函数,所以派生类对象一开始要4个字节存储指向虚函数表的指针。
然后继承D中的数据成员double d;
它要8字节对齐,所以前面空4个字节。
下面就开始存储d0,c,d1.最后类对齐可计算得到32.
C++类的存储(部分可用与c的结构体)的更多相关文章
- swift学习笔记3——类、结构体、枚举
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- 5.Swift枚举|结构体|类|属性|方法|下标脚本|继承
1. 枚举: ->在Swift中依然适用整数来标示枚举值,需搭配case关键字 enum Celebrity{ case DongXie,XiDu,Nandi,BeiGai } // 从左 ...
- 全面总结sizeof的用法(定义、语法、指针变量、数组、结构体、类、联合体、位域位段)
一.前言 编译环境是vs2010(32位). <span style="font-size:18px;">#include<iostream> #inclu ...
- 【Swift学习】Swift编程之旅---类和结构体(十三)
与其他编程语言所不同的是,Swift 并不要求你为自定义类和结构去创建独立的接口和实现文件.你所要做的是在一个单一文件中定义一个类或者结构体,系统将会自动生成面向其它代码的外部接口. 注意:通常一个类 ...
- C#中的结构体与类的区别
经常听到有朋友在讨论C#中的结构与类有什么区别.正好这几日闲来无事,自己总结一下,希望大家指点. 1. 首先是语法定义上的区别啦,这个就不用多说了.定义类使用关键字class 定义结构使用关键字str ...
- Swift枚举|结构体|类|属性|方法|下标脚本|继承
1. 枚举: ->在Swift中依然适用整数来标示枚举值,需搭配case关键字 enum Celebrity{ case DongXie,XiDu,Nandi,BeiGai } // 从左 ...
- Swift: 类与结构体
对比类与结构体 类与结构体有许多的相同点,它们都可以: 定义属性来存储值: 定义方法来提供功能: 定义下标操作: 定义初始化函数: 扩展它的默认的实现: 遵从协议: 类有一些额外的能力,但是结构体没有 ...
- swift 学习- 10 -- 类和结构体
// '类和结构体' 是人们构建代码所使用的一种通用且灵活的构造体, 我们可以使用完全相同的语法规则来为 '类和结构体' 定义属性 (变量 和 常量) 和添加方法, 从而扩展 类和结构体 的功能 // ...
- 浅析C#中的结构体和类
类和结构是 .NET Framework 中的常规类型系统的两种基本构造. 两者在本质上都属于数据结构.封装着一组总体作为一个逻辑单位的数据和行为. 数据和行为是该类或结构的"成员" ...
随机推荐
- UVALive 2323 Modular Multiplication of Polynomials(模拟)
这是一个相对简单的模拟,因为运算规则已经告诉了我们,并且比较简单,不要被吓到…… 思路:多项式除以另外一个多项式,如果能除,那么他的最高次一定被降低了,如果最高次不能被降低,那说明已经无法被除,就是题 ...
- map.entry<k,v>小用法(转)
你是否已经对每次从Map中取得关键字然后再取得相应的值感觉厌倦?使用Map.Entry类,你可以得到在同一时间得到所有的信息.标准的Map访问方法如下: Set keys = map.keySet( ...
- Oracle Sql优化之范围处理
1.表中字段自关联与分析函数的性能比较,自关联需要扫描表两次,分析函数扫描一次即可 ----自关联 select v1.proj_id,v1.proj_start,v1.proj_end from v ...
- 用cas来实现php的单点登陆
最近项目中需要做单点登录,客户端包含Java.ruby和PHP,java有几个应用程序,php是discuz+supesite+ucenter,配置步骤如下: 1.cas服务端:下载地址:http:/ ...
- Chapter 1 First Sight——19
"I'm headed toward building four, I could show you the way…" Definitely over-helpful. &quo ...
- 向页面动态添加外部js
var script = document.createElement("script"); script.src = '/static/js/view/'+url+'.js'; ...
- jq的遍历节点
1.child()方法 该方法用于取得匹配元素的子元素集合 2.next() 该方法用于取得匹配元素后面紧邻的同辈元素, 3.prev() 该方法用于取得匹配元素前面紧邻的同辈元素 4.sibling ...
- 让shell 变得容易理解
1.重建你的语义模型(简单语义模型)2.变量,参数和方法命名3.测试用例4.足够的组块
- 核心动画 CAAnimation 进阶
转载自:http://www.cofcool.net/development/2015/06/20/ios-study-note-nine-CoreAnimation/ Core Animation, ...
- ARM系统中函数调用过程中的参数传递-转
在 嵌入式软件编程中,经常会用到函数调用,之前在学习如何在C语言中嵌入汇编时有了解到C语言之前的参数调用是使用寄存器R0传递第一个参数,R1传递到第 二个..一直到R3传递第四个参数.但是实际上有时可 ...