《深度探索C++对象模型》学习笔记之Data语意学

在写这个之前,我为毛觉得莫名激动,为何上篇文章阅读量都破三百了,难道是提到了什么了不得的关键字啊啊哈哈哈我不啰嗦了
你觉得一下代码结果是什么呢?

#include<iostream>
using namespace std;
class A
{
};
class Y:public virtual A
{};
class X:public virtual A
{};
class Z:public X,public Y
{};
int main()
{
    A a;
    X x;
    Y y;
    Z z;
    cout<<sizeof(a)<<endl;
    cout<<sizeof(y)<<endl;
    cout<<sizeof(x)<<endl;
    cout<<sizeof(z)<<endl;
}

我在Visual C++6.0上的执行结果和侯捷老师是一样的1,4,4,8
让我们来分析一下一下这个结果,类a实际上并不是空的,它有一个隐晦的1byte,是被编译器安插进去一个char,使得class的每个对象在内存中配置独一无二的地址。这里遗留一个问题,就是这个1byte到底是什么呢。。我调试的结果是这样子这里写图片描述
电脑好卡,我快要编不下去了。。
x和y的大小受到三个因素的影响:
* 语言本身所造成的额外负担,举个例子比如说支持虚基类时,在其派生类时,就会有某种形式的指指针。
* 编译器对于特殊情况所提供的优化处理
* 字节对齐的限制
该图是作者编译器的内存图这里写图片描述

不过上图对应的答案是1,8,8,12就是作者的编译器
class z的大小12来自一下原因:
* 被大家共享的一个唯一的class a实体,1byte
* base class Y的大小,减去“因virtual base class x”而配置的带下,结果是4bytes
* class z自己的大小:0byte
* 对齐数量,前面加起来是9,填充3个
我的1,4,4,8对应的图在这里
这里写图片描述
这里解释我的8的来由,对empty virtual base class做了处理,class
x实体的1byte被拿掉

每一个类对象的大小必须能容纳它的非静态数据成员,结果可能比想象中的要多。原因:
* 编译器自动加上额外的数据成员
* 边界调整的需要

数据成员的布局

规定:较晚出现的成员在类对象中有较高的地址。如何理解呢,就是说多个成员不一定得连续排列,那么什么东西可能在这些被声明的成员之间呢?不如说!vptr啊,以支持整个对象模型,当前所有编译器把它安排在一个内含虚函数的类的对象内 ,传统上它被放在所有明确声明的成员的最后,不传统的我们就不讨论了啊哈。
数据成员依照权限设置,按照声明的次序来成为一个连续区块,权限部分的多少不会由额外负担。这个很好理解的,比如说在一个section中声明8个成员,或是在8个section中总共声明8个成员,得到的对象大小是一样的

静态数据成员

提出与class之外,并被视为一个global变量(但只在class生命范围内可见)。每一个静态数据成员只有一个实体,存放在程序的数据段中,这时通过指针和通过对象来存取成员,结论完全相同的唯一情况,因为,经由.运算符来操作静态数据成员仅仅是语法上的一种便宜行事而已,成员并不在类对象中,因此存取它不需要通过类对象。(网易云音乐随机播放到CNBLUE的孤独的人,我好悲伤。。那是我手机的铃声啊。。可是我没有手机了啊。。请允许我做一个悲伤的表情)
若取一个静态数据成员的地址,会得到一个只想其数据类型的指针,而不是只想其类成员的指针,因为静态成员并不在一个对象中,书上是这么说的,那么问题来了,如何通过代码来看呢,我不知道。经过查阅资料得知,这里的一个字节就是一个占位符。这里写图片描述

非静态数据成员

这类直接存放在每一个类对象之中,每一个非静态数据成员的偏移量在编译期就可以获得。回到最初这个问题,从对象存取和从指针存取的差别呢,如果是一个派生类,而在其继承结构中有一个虚基类,而且被存取的成员是一个从该基类继承而来的成员时,就会有很大差异,因为我们不能说指针必然指向哪一个类因此我们也就不知道编译时期这个成员真正的偏移量,所以这个存取操作要推迟导执行期但是用对象得救不会有这么多的问题了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值