浅谈C++类大小以及内存布局
来源:互联网 发布:linux 禁用ping 编辑:程序博客网 时间:2024/06/14 21:14
写代码不自然的都会用到有关Class的内容,现在我来浅谈一下关于Class大小以及内存布局的一些问题。
(1)空类
class CEmpty{};//size = 1
注:为什么时间大小为0编译器(vs13)却要定义成1呢?
C++标准中规定,"No object shall have the same address in memory as any other variable",试想一下,我们如果定义一个CEmpty对象数组,那么如果类大小为0,所有生成的对象在内存中都指向了同一个地址,我们无法通过索引Index对对象进行选择,所以类大小为0显然违背标准。
class CEmpty_MemberFunc{void print(){std::cout << "CEmpty_MemberFunc's print";}};//size = 1
注:类成员函数并不会影响类大小
class CEmpty_STATIC_Member{static int nA;};//size = 1
注:static成员变量存放区域为全局数据区,在类生成对象之前进行初始化,并不影响类大小
class CEmpty_STATIC_Function{static int static_print(){std::cout << "CEmpty_STATIC_Function's static_print";}};//size = 1
注:static函数表明函数的作用范围,并不会影响类大小
(2)简单类
class CTwo_Member{int a;char b;};//size = 8 if pack(4)
class CDeclaration_Struct_And_Two_Member{struct Struct{int a1;char a2;short a3;long long a7;char a4;long long a5;char a6;};int a;char b;};//size =8
注:可见结构体只声明并不会影响内存大小
class CStruct_And_Two_Member{struct Struct{int a1;char a2;short a3;long long a7;char a4;long long a5;char a6;}S1; //size = 40int a;char b;};size = 48
注:可见结构体对齐大小不影响类成员对齐大小,结构体大小影响类大小
(3)简单继承类
class CInherit_empty : public CEmpty{int a;};//size = 4
注:继承空类,类的大小是继承类大小
(4)含虚拟函数的类
class CVirtual_One_Member{ virtual int virtual_fun1(); virtual int virtual_fun2();};//size = 4
注:类的虚函数保存在虚函数表vfptr中,类大小为4
(5)含虚拟函数类的继承
class CInherit_vitrual_one_member : public CVirtual_One_Member{int virtual_fun1();int virtual_fun2();virtual int virtual_fun3();};//size = 4 虽然没有virtual关键字,但是和基类函数相同,默认为virtual
注:可见vfun1,vfun2依旧是虚函数,vfun3保存在vfptr中
(6)虚继承
class CVirtual_Inherit_vitrual_one_member :virtual public CVirtual_One_Member{virtual int virtual_fun3();};//size = 12
注:由布局信息可见:虚继承会产生一个自己的vfptrc存储新产生的vfun3,产生一个vbptr指向虚基类偏移量,加上继承一个基类虚函数表,所以类大小12
(7)闭合虚继承
如图:
class CVirtual_Inherit_vitrual_one_memberA :virtual public CVirtual_One_Member{int a;virtual int virtual_funa();};//size = 16class CVirtual_Inherit_vitrual_one_memberB :virtual public CVirtual_One_Member{int b;virtual int virtual_funb();};//size = 16class CInherit_vitrual_one_memberAB :public CVirtual_Inherit_vitrual_one_memberA,public CVirtual_Inherit_vitrual_one_memberB{int c;virtual int virtual_func();};//size = 32
AB:
注:由图可知虚继承基类放在了内存布局最后,指向同一空间,A,B产生了两个不同的vfptr以及不同的vbptr,func存放在A的vfptr中(根据继承顺序,放在A),AB类大小=A类大小(16)+B类大小(16)+AB类成员大小(4) - 重复的(AB指向同一基类)基类大小(4) = 32
混合多继承(略)
总结:
(1)普通单继承:子类如果有虚函数,父类如果有虚表,子类沿用父类虚表,没有则产生虚表。
(2)普通多继承:子类如果有虚函数则继承第一个父类的虚表,有多少个有虚函数的父类就有多少个虚表。
(3)虚拟单继承:子类有虚函数产生自己的虚表,并产生vbptr指向父虚基类偏移量,如果父虚基类有虚函数也继承父类的虚表。
(4)多重虚继承:子类如有虚函数则产生自己的虚表,虚拟继承于同一祖父类的父类则只有同一个祖父类虚表。
(5)普通,虚拟混合多继承:记住虚继承产生子类自己的虚表和指向父类的偏移指针,闭合虚继承不管父类有多少,只继承一个祖父类虚表。
欢迎大家一起讨论!
- 浅谈C++类大小以及内存布局
- Java内存布局浅谈
- Java内存布局浅谈
- 数组 指针 内存 布局 大小端 汇编 c语言
- C程序中内存布局&Union大小尾端
- 内存布局-大小端模式
- 浅谈对象的内存布局
- 浅谈C++对象内存布局
- 浅谈C++对象内存布局
- 浅谈C++中派生类对象的内存布局
- C语言内存浅谈
- C语言内存浅谈
- c程序内存布局
- C/C++ 内存布局
- Objective-C内存布局
- C/C++ 内存布局
- Objective-C内存布局
- Objective-C内存布局
- B\S备忘录15——旁友,票子要伐
- spring 注解实现注入
- 非递归解决leetcode Minimum Depth of Binary Tree
- Java之Socket与HTTP区别
- Java从HashSet中取元素
- 浅谈C++类大小以及内存布局
- centos7 mysql The server quit without updating PID file(错误解决)
- Android广播机制---发送本地广播_android全局信息处理本地广播安全广播
- Java-泛型 <T>
- spring IOC
- Java中HashSet的用法
- 随笔《HTML》
- java内存结构
- 第2条:遇到多个构造器参数时要考虑用构建器