class X{};
class Y :public virtual X{};
class Z :public virtual X{};
class A :public Y, public Z{};
void main()
{
cout << sizeof(X) << " " << sizeof(Y) << " " << sizeof(Z) << " " << sizeof(A);
system("pause");
}

vs2013的结果是1,4,4,8

因为Y,Z继承自X,会有指针指向父类(虚继承)。该指针要么指向virtual base class subobject,要么指向一个相关表格,表格中存放的是virtual base class subobject的地址或偏移量(一般当当前class有多个直接virtual base class时)。

X内部的1byte,使得这个class的多个object得以在内存中配置独一无二的地址。

empty virtual base class 被视为derived class object 最开头的一部分,也就是说派生类有了member,那么就不需要原本因为empty class而插入的一个byte。

A为普通继承,所以是父类的和。

一、data member的布局

nonstatic data members在class object中的排列顺序将和其被声明的顺序一样,任何中间介入的static data member都不会被放进对象布局中。

C++standard要求,在同一个access section中,member的排列只需符合较晚出现的member在class object中有较高的地址即可,各个member并不一定得连续排列。

编译器可能会合成一些内部使用的data member,以支持整个对象模型,vptr就是这样的东西,当前所有的编译器都把它安插在每一个内含virtual function之class的object内,vptr的安放位置依不同的编译器决定。

二、data member的存取

1.static data member

每一个static data member只有一个实体,存放在程序的data segment之中,并不再class object中,每次程序取用static member,就会被内部转化为对该唯一的extern实体的直接操作,也就是说通过一个指针和通过一个对象来存取static data member完全相同。

通过对象存取static data member只是语法上的方便而已,static data member并不再class object中,因此存取static member 不需要通过class object。

2.nonstatic data member

Point3D origin,*pt=&origin;
origin.x=;
pt->x=;

当Point3D是一个derived  class,而在其继承结构中有一个virtual base class,并且被存取的member是一个从该virtual base class继承而来的member时,上述两种方式有重大差异。这时候我们不知道pt指向哪一个class,所以这个存取操作必须延迟到程序运行时。但使用origin,member的offset位置在编译期间就固定了。

欲对一个nonstatic data member进行存取操作,编译器需要把class object的起始地址加上data member的偏移量(offset)。

 三、继承与data member

1.只有继承无多态的情况

class concrete1
{
public:
//...
private:
int val;
char bit1;
}; class concrete2:public concrete1
{
public :
//..
private:
char bit2;
}; class concrete3 :public concrete2
{
public :
//..
private:
char bit3;
}; void main()
{
cout << sizeof(concrete1) << " " << sizeof(concrete2) << " " << sizeof(concrete3);
system("pause");
}

输出值是8,12,16

alignment的限制,使得类在内存中的存取更有效率,在32位计算机中,alignment通常为4bytes,刚好为一个word

为何派生类成员不放在基类因为边界调整而多占的空间上呢?

派生类对象拷贝给基类对象时,只有基类部分才会拷贝给基类对象,派生类部分被切割,如果不是按照上述的设计,就不能实现这一点

(方向应该反过来看)

【深度探索C++对象模型】data语义学的更多相关文章

  1. 《深度探索C++对象模型》读书笔记(一)

    前言 今年中下旬就要找工作了,我计划从现在就开始准备一些面试中会问到的基础知识,包括C++.操作系统.计算机网络.算法和数据结构等.C++就先从这本<深度探索C++对象模型>开始.不同于& ...

  2. [读书系列] 深度探索C++对象模型 初读

    2012年底-2014年初这段时间主要用C++做手游开发,时隔3年,重新拿起<深度探索C++对象模型>这本书,感觉生疏了很多,如果按前阵子的生疏度来说,现在不借助Visual Studio ...

  3. 拾遗与填坑《深度探索C++对象模型》3.3节

    <深度探索C++对象模型>是一本好书,该书作者也是<C++ Primer>的作者,一位绝对的C++大师.诚然该书中也有多多少少的错误一直为人所诟病,但这仍然不妨碍称其为一本好书 ...

  4. 拾遗与填坑《深度探索C++对象模型》3.2节

    <深度探索C++对象模型>是一本好书,该书作者也是<C++ Primer>的作者,一位绝对的C++大师.诚然该书中也有多多少少的错误一直为人所诟病,但这仍然不妨碍称其为一本好书 ...

  5. 深度探索C++对象模型

    深度探索C++对象模型 什么是C++对象模型: 语言中直接支持面向对象程序设计的部分. 对于各个支持的底层实现机制. 抽象性与实际性之间找出平衡点, 需要知识, 经验以及许多思考. 导读 这本书是C+ ...

  6. c++学习书籍推荐《深度探索C++对象模型》下载

    百度云及其他网盘下载地址:点我 百度云及其他网盘下载地址:点我 编辑推荐 如果你是一位C++程序员,渴望对于底层知识获得一个完整的了解,那么这本<深度探索C++对象模型>正适合你 作者简介 ...

  7. 读书笔记《深度探索c++对象模型》 概述

    <深度探索c++对象模型>这本书是我工作一段时间后想更深入了解C++的底层实现知识,如内存布局.模型.内存大小.继承.虚函数表等而阅读的:此外在很多面试或者工作中,对底层的知识的足够了解也 ...

  8. 柔性数组-读《深度探索C++对象模型》有感 (转载)

    最近在看<深度探索C++对象模型>,对于Struct的用法中,发现有一些地方值得我们借鉴的地方,特此和大家分享一下,此间内容包含了网上搜集的一些资料,同时感谢提供这些信息的作者. 原文如下 ...

  9. 柔性数组-读《深度探索C++对象模型》有感

    最近在看<深度探索C++对象模型>,对于Struct的用法中,发现有一些地方值得我们借鉴的地方,特此和大家分享一下,此间内容包含了网上搜集的一些资料,同时感谢提供这些信息的作者. 原文如下 ...

随机推荐

  1. c语言 预处理的使用 宏展开下的#,##

    1. #include   包含头文件 2.define 宏定义(可以理解为替换,不进行语法检查) 写法 #define 宏名 宏体  加括号 #define ABC (5+3) #define AB ...

  2. && (and)、||(or) 条件语句

    当前面条件满足时,就执行后面的代码 //条件为真时,就执行其中的语句 if($a>0){ $b='This is test'; } //上面的写法太麻烦,可以这样简写 $a>0 & ...

  3. 获取指定点的RGB值

    实现效果: 知识运用: Color对象的RGB属性 实现代码: private void button1_Click(object sender, EventArgs e) { OpenFileDia ...

  4. 安卓获取数据demo出现的问题

    时间戳是long型的数据,但其他数据都是float型,但AsyncTask要求是统一数据类型.这样我就不能把时间戳放进AsyncTask里面进行处理,我就在doInBackground中获取时间戳然后 ...

  5. Caused by: java.lang.ClassNotFoundException: Cannot find class: User

    源代码: <select id="selectAll" resultType="User"> select user_id uid,user_nam ...

  6. MySQL-01 MySQL数据库安装指南

    学习要点 MySQL数据库的安装和设置 下载mysql mysql官网:https://www.mysql.com/downloads/ 主要版本: Oracle MySQL Cloud Servic ...

  7. 收集的WEB前端程序员需要的网站整理

    前端学习资源实在是又多又广,在这样的一个知识的海洋里,我们像一块海绵一样吸收,想要快速提高效率,平时的总结不可缺少,以下总结了一些,排版自我感觉良好,推送出来. 一.插件类网站 jQuery插件库:h ...

  8. vue在传值的时候经常遇到的问题

    在我用vue编写程序的时候,在传值的时候,经常会遇到些问题,像今天遇到了两个问题,在用父传子的方法去传值,当父组件中的要传的数据是for循环出来的或者是列表的时候,你想每次运行的事件,都去传某一行,或 ...

  9. img元素srcset属性浅析

    img srcset 属性 img 元素的 srcset 属性用于浏览器根据宽.高和像素密度来加载相应的图片资源. 属性格式:图片地址 宽度描述w 像素密度描述x,多个资源之间用逗号分隔.例如: &l ...

  10. ubuntu卸载编译安装的软件

    cd 源代码目录 make clean ./configure make make uninstall