深入探索C++对象模型-1
概述
在实际生产中,遇到一个复杂的类,如果能看出这个类的内存模型结构,那么以后的操作基本就没有难度的;
所以说,学会分析一个类的内存模型,是每一个C++程序员必须要会的知识。
下面,就让我们来了解C++对象模型!
C++类封装和C中的结构体的区别
C++的类封装是在C语言中的结构体的基础上构建起来的,C结构体只允许存在数据,而不会存在对数据的操作。
C++语言中延承C语言中的结构体,但增加的对数据的操作,即成员函数;
类是对结构体的进一步封装,使某些数据成员对外不可见,称为私有成员。
类和结构体最大的区别就是:结构体成员均是public类型的。
那么,类和结构体的布局成本有没有区别呢?
对于只有数据成员的类和结构体在内存的布局是相同的,没有增加成本。
而members functions 虽然含在class的声明之内,却不出现在object之中。每一个 non-inline member fuction 只会诞生一个函数实体,调用时链接至函数体。至于每一个"拥有零个或一个定义"的 inline function 则会在其每一个调用者(模块)身上产生一个函数实体。
在C++中,有两种 class data members: static 和 nonstatic,以及三种 class member functions : static、nonstatic 和 virtual。
在C++对象模型中,非静态数据成员被配置在每一个 class object 之内,静态数据成员则被存在个别的 class object 之外,静态和非静态的成员函数也被放在个别的 class object 之外。
C++在布局及存取时间上主要的额外负担是由 virtual 引起。包括:
- virtual function 机制:用以支持一个有效率的"执行期绑定"
- virtual base class 用以实现"多次出现在集成体系中的base class,有一个单一而被共享的实体。
虚函数以及虚函数表
虚拟函数的实现
1.每一个 class 产生一堆指向虚函数的指针,放在表格之中,这个表格被称为 virtual table(vtbl);
2.每一个 class object 被安插一个指针,指向相关的 virtual table。这个指针通常被称为 vptr。vptr 的设定和重置都由每一个类的构造函数、析构函数和赋值操作符重载函数自动完成且一旦完成初始化不能修 改。每一个类所关联的type_info object(主要用于RTTI)也经由 virtual table被指出来,通常放在表格的第一个slot。
多重继承模型
C++最初采用的继承模型时间基类对象中的数据成员直接存放在继承类对象内存中,包括基类对象的虚函数表和虚指针(貌似现在也是这样的模型),这样就可以对基类成员进行最有效率的存取,然而缺点是如果基类成员有任何的修改将会导致基类对象和继承类对象的重新编译。
有人提出一种间接存取模型:在继承类对象中放置一指针Bptr,该指针指向继承类的基类表,类似与虚函数表,基类表中每一项都指向继承类对象的基类 对象。这样的好处是,基类对象的任何改变吗都不会影响到继承类对象的内存布局,缺点是导致对基类对象成员的存取效率低,随着继承深度的增加,间接性越强, 效率越低。
因此又有人提出,在继承类对象中放置与基类相等数目的指针指向每个基类,这样存取时间就恒久不变了,但是这样无疑增加了继承类的内存开销。
目前使用的多重继承模型仍为第一种,继承类对象中含有所有基类对象数据成员和虚指针,同时继承基类的虚函数表共享为继承类的虚函数表。
虚拟继承模型
虚拟继承保证继承类中只含有一个基类对象,继承类中会产生虚指针指向虚表中offset指向继承类中的基类对象。只有直接虚继承的继承类对象才会产生Vptr。
目前,关于虚拟继承的继承类的内存布局有三种模型:
1、原始模型:在每个继承类对象中设置指针,用以指向继承类中的基类对象。优点:通过指针能够保证继承类中只有一个基类对象,可以直接存取基类对象。缺点:若继承类有多个虚拟基类,则需要多个指针指向基类们,会消耗较多的内存。
2、有人提出像虚函数表一样,提供一个虚拟基类表virtual base class table,表中每个slot指向一个基类对象的地址。在继承类对象中,设置一个虚拟基类表指针指向基类表。优点:继承类减少了因虚拟基类指针而产生的开 销,且继承类不会因为虚拟基类的增加而改变内存模型。缺点:存取基类对象数据成员会导致效率低下。
3、现在最常用的模型:扩充原Virtual table,在虚表负offset位置指向虚基类对象,因此,只要是虚继承就会产生虚指针和虚表。
虚拟多继承,采用“钻石”继承结构,其每个类的内存分布如下图:其中虚指针的位置可以在顶部或尾部。
上述内容是类对象内存模型的介绍:
(1)无虚函数和虚继承:nostatic数据成员存放在对象中,static数据成员存放在对象外属于整个类。nostatic和static函数成员均放在对象外。
(2)有虚函数和虚继承:virtual函数放在虚函数表中,通过虚指针进行查找调用。基类对象数据成员和虚指针均存放在继承类的对象中。
深入探索C++对象模型-1的更多相关文章
- 读书笔记《深度探索c++对象模型》 概述
<深度探索c++对象模型>这本书是我工作一段时间后想更深入了解C++的底层实现知识,如内存布局.模型.内存大小.继承.虚函数表等而阅读的:此外在很多面试或者工作中,对底层的知识的足够了解也 ...
- 柔性数组-读《深度探索C++对象模型》有感 (转载)
最近在看<深度探索C++对象模型>,对于Struct的用法中,发现有一些地方值得我们借鉴的地方,特此和大家分享一下,此间内容包含了网上搜集的一些资料,同时感谢提供这些信息的作者. 原文如下 ...
- 柔性数组-读《深度探索C++对象模型》有感
最近在看<深度探索C++对象模型>,对于Struct的用法中,发现有一些地方值得我们借鉴的地方,特此和大家分享一下,此间内容包含了网上搜集的一些资料,同时感谢提供这些信息的作者. 原文如下 ...
- [读书系列] 深度探索C++对象模型 初读
2012年底-2014年初这段时间主要用C++做手游开发,时隔3年,重新拿起<深度探索C++对象模型>这本书,感觉生疏了很多,如果按前阵子的生疏度来说,现在不借助Visual Studio ...
- 拾遗与填坑《深度探索C++对象模型》3.3节
<深度探索C++对象模型>是一本好书,该书作者也是<C++ Primer>的作者,一位绝对的C++大师.诚然该书中也有多多少少的错误一直为人所诟病,但这仍然不妨碍称其为一本好书 ...
- 拾遗与填坑《深度探索C++对象模型》3.2节
<深度探索C++对象模型>是一本好书,该书作者也是<C++ Primer>的作者,一位绝对的C++大师.诚然该书中也有多多少少的错误一直为人所诟病,但这仍然不妨碍称其为一本好书 ...
- 深度探索C++对象模型
深度探索C++对象模型 什么是C++对象模型: 语言中直接支持面向对象程序设计的部分. 对于各个支持的底层实现机制. 抽象性与实际性之间找出平衡点, 需要知识, 经验以及许多思考. 导读 这本书是C+ ...
- 《深度探索C++对象模型》读书笔记(一)
前言 今年中下旬就要找工作了,我计划从现在就开始准备一些面试中会问到的基础知识,包括C++.操作系统.计算机网络.算法和数据结构等.C++就先从这本<深度探索C++对象模型>开始.不同于& ...
- C++的黑科技(深入探索C++对象模型)
周二面了腾讯,之前只投了TST内推,貌似就是TST面试了 其中有一个问题,“如何产生一个不能被继承的类”,这道题我反反复复只想到,将父类的构造函数私有,让子类不能调用,最后归结出一个单例模式,但面试官 ...
- 深入探索C++对象模型(一)
再读<深入探索C++对象模型>笔记. 关于对象 C++在加入封装后(只含有数据成员和普通成员函数)的布局成本增加了多少? 答案是并没有增加布局成本.就像C struct一样,memeber ...
随机推荐
- 简单实现tab标签页切换
常见面试题: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
- 我和CPP的第二次约会
1.变量之间的运算形式依赖于变量的数据类型,如i = i + j;当 i 和 j 是整型或者浮点型,则代表两个数的相加,如果是第一章所说的Sales_item类型,那么就是这两个变量的成分相加(如果书 ...
- action 关联
<act_window context="{'product_id': active_id}" id="act_stock_product_location_ope ...
- [r]How To Use Git To Create A Key
怎样生成公钥(via) 工作流程 安装设置 git 下载最新版本的git http://git-scm.com/downloads 当你安装完成git的时候,你需要简单的配置一下,打开终端: 用户名 ...
- 【Linux】 诊断工具-strace
1,别人家的总结: http://www.cnblogs.com/bangerlee/archive/2012/02/20/2356818.html 2,我自己碰到问题: 暂无. 3,使用场景: 程序 ...
- JSP 2秒跳转到首页
<%@ page contentType="text/html;charset=utf-8" pageEncoding="utf-8"%><h ...
- HTML/W3C-WHATWG-Differences
Differences between the W3C HTML 5.1 specification and the WHATWG LS The W3C HTML 5.1 specification: ...
- cf B Bear and Strings
题意:给你一个字符串,然后找多少区间内含有“bear”,输出数目: #include <cstdio> #include <cstring> #include <algo ...
- 给java中的System.getProperty添加新的key value对
由于系统被格了,所以,现在的java项目配置不对,代码里面的配置类调用了一个System.getProperty("env")发现找不到该变量的值,以前一直能找到的. 其实就是以前 ...
- Apache CXF多个远程拒绝服务漏洞(CVE-2013-2160)
漏洞版本: Apache Group CXF <= 2.5.10 Apache Group CXF 2.7.4 Apache Group CXF 2.6.7 漏洞描述: BUGTRAQ ID: ...