《深度探索C++对象模型》第一章 | 关于对象
C++对象模式
非静态数据成员放置在每个类对象内,静态数据成员则被放置在所有类对象之外。静态和非静态的成员函数也被放置在所有类对象之外。每个类产生一堆指向虚函数的指针,放在虚表(vtbl)中。每个类对象维护一个指针(vptr),指向相关的虚表。虚表的首元素维护了每个类所关联的type_info对象。
优点:空间与存取时间效率高
缺点:一旦所用到的类对象的非静态数据成员有所修改,那么代码就要重新编译
加上继承
C++支持单一继承、多重继承和虚拟继承。在虚拟继承的情况下,基类不管在继承链中被派生多少次,永远只会存在一个实体。
C++中凡是处于同一个访问控制修饰符下的数据,必定保证以其生命的次序出现在内存布局中。然而被放置在多个访问控制修饰符下的各笔数据,内存的排布顺序就不一定了。同样的道理,基类和派生类的内存布局也没有谁先谁后的强制规定。虚函数也会对内存布局产生影响。
对象的差异
只有通过指针或者引用间接处理基类对象,才能支持面向对象程序设计所需的多态性质。
C++以下列方法支持多态:
- 经由一组隐含的转化操作,例如把一个派生类指针转化为一个基类的指针
- 经由虚函数机制
- 经由
dynamic_cast和typeid运算符
类对象的内存
- 其非静态数据成员的总和
- 加上任何由于内存对齐而填补的空间
- 加上为了支持虚函数而内部产生的额外负担
void*类型的指针只表示一个地址,不能够通过它操作所指的对象。类型转换其实是一种编译器指令,大部分情况下它不改变一个指针所含的真正地址,只影响“被指向的内存大小和其内容”的解释方式。
加上多态之后
class Bear : public ZooAnimal{
public:
Bear();
~Bear();
// ...
void rotate();
virtual void dance();
// ...
protected:
enum Dances { ... };
Dances dances_known;
int cell_block;
};
Bear b;
ZooAnimal *pz = &b;
Bear *pb = &b;
这两个指针都指向Bear对象的首个字节,差别是pb所涵盖的地址包含整个Bear对象,而pz所涵盖的地址只包含Bear对象中的ZooAnimal部分。除了ZooAnimal对象中出现的成员,不能用pz直接处理Bear的任何成员,除非使用虚函数机制:
pz->cell_block; // 不合法
((Bear*)pz)->cell_block; // 合法
dynamic_cast<Bear*>(pz)->cell_block; // 合法
pb->cell_block; // 合法
当我们写下代码pz->rotate();时,pz的类型将在编译期决定以下两点:
- 固定的可用接口,即
pz只能调用ZooAnimal的public接口 - 该接口的访问权限
在执行期,pz所指的对象类型可以决定rotate()所调用的实体(即动态绑定)。类型信息的封装并不维护于pz中,而是维护于对象的虚函数指针和该指针所指的虚表之间。
对于下面这种情况,为什么rotate()所调用的是ZooAnimal实体而不是Bear实体呢?此外,如果初始化函数(赋值操作)将一个对象的内容完整地拷贝到另一个对象中,为什么za的虚指针不指向Bear的虚表呢?
Bear b;
ZooAnimal za = b; // 会引起切割
// 调用 ZooAnimal::rotate()
za.rotate();
因为za本身是一个ZooAnimal对象而非Bear对象,所以它并不能调用Bear类型的方法。当一个基类对象被指定为派生类对象时,派生类就会被切割,以塞入较小的基类对象的内存中。因此,该基类对象就不能访问派生类的成员。而指针或者引用之所以支持多态,是因为它们不会引发内存中任何“与类型有关的内存委托操作”,改变的只是它们所指向的内存的“大小和内容解释方式”而已。
对于第二个问题,编译器在初始化和赋值操作之间做出了仲裁。编译器必须确保如果某个对象含有一个或一个以上的虚指针,那些虚指针的内容不会被基类对象初始化或改变。
《深度探索C++对象模型》第一章 | 关于对象的更多相关文章
- 深度探索c++对象模型 第一章
1,声明与定义. //声明式如下: extern int x; //对象式(变量式)声明 std::size_t numDigits(int number); //函数式声明 class Wid ...
- 【C++】深度探索C++对象模型读书笔记--关于对象(Object Lessons)
前言中的内容: 1.什么是C++对象模型? 1.语言中直接支持面向对象程序设计的部分 2. 对于各种支持的底层实现机制 2. C++ class的完整virtual functions在编译时期就固定 ...
- 《深度探索c++对象模型》chapter1关于对象对象模型
在c++中,有2种class data member:static和nostatic,以及3钟class member function:static,nostatic和virtual.已知下面这个c ...
- 深度探索c++对象模型 第二章
1,c++转换函数:显示转换和隐式转换. 隐式转换为程序员提供了很大的变量.比如整形提升,普通类型转换为类类型(operator int())都为程序带来无尽的方便.试想,如果没有整形提升,一个sho ...
- Android深度探索-卷1第一章心得体会
本章介绍了安卓系统移植与驱动开发的概述,安卓的系统架构有四层:1 Linux内核,2 c/c++代码库, 3 Android SDK API, 4 应用程序 在读的过程中看到了专业名词,查了查,长点 ...
- 拾遗与填坑《深度探索C++对象模型》3.3节
<深度探索C++对象模型>是一本好书,该书作者也是<C++ Primer>的作者,一位绝对的C++大师.诚然该书中也有多多少少的错误一直为人所诟病,但这仍然不妨碍称其为一本好书 ...
- 拾遗与填坑《深度探索C++对象模型》3.2节
<深度探索C++对象模型>是一本好书,该书作者也是<C++ Primer>的作者,一位绝对的C++大师.诚然该书中也有多多少少的错误一直为人所诟病,但这仍然不妨碍称其为一本好书 ...
- 《深度探索C++对象模型》读书笔记(一)
前言 今年中下旬就要找工作了,我计划从现在就开始准备一些面试中会问到的基础知识,包括C++.操作系统.计算机网络.算法和数据结构等.C++就先从这本<深度探索C++对象模型>开始.不同于& ...
- 深度探索C++对象模型
深度探索C++对象模型 什么是C++对象模型: 语言中直接支持面向对象程序设计的部分. 对于各个支持的底层实现机制. 抽象性与实际性之间找出平衡点, 需要知识, 经验以及许多思考. 导读 这本书是C+ ...
- c++学习书籍推荐《深度探索C++对象模型》下载
百度云及其他网盘下载地址:点我 百度云及其他网盘下载地址:点我 编辑推荐 如果你是一位C++程序员,渴望对于底层知识获得一个完整的了解,那么这本<深度探索C++对象模型>正适合你 作者简介 ...
随机推荐
- 强化学习实战 | 自定义gym环境之显示字符串
如果想用强化学习去实现扫雷.2048这种带有数字提示信息的游戏,自然是希望自定义 gym 环境时能把字符显示出来.上网查了很久,没有找到gym自带的图形工具Viewer可以显示字符串的信息,反而是通过 ...
- vps上安装CobaltStrike服务端
今天我在我的vps上安装CobaltStrike服务端,真的是踩坑无数,所以写这篇博客记录一下,防止后人再踩坑 安装Oracle JDK8 官方不建议使用OpenJdk,建议使用Oracle JDK的 ...
- python环境搭建以及jupyter notebook的安装和启动
一.Python 环境搭建 本章节我们将向大家介绍如何在本地搭建Python开发环境. Python可应用于多平台包括 Linux 和 Mac OS X. 你可以通过终端窗口输入 "pyth ...
- python极简教程07:封装、多态和继承
测试奇谭,BUG不见. 这一场主讲python的面向对象部分--封装.多态和继承. 目的:掌握Python面向对象的三个核心概念. 封装 01 什么是封装? 封装的目的是,保护隐私.通俗的讲:不想让别 ...
- C# 余一问题 奇偶数求和问题
编写程序,用 while 循环语句实现下列功能:有一篮鸡蛋,不止一个,有人两个两个数,多余一个,三个三个数,多余一个,再四个四个地数,也多余一个,请问这篮鸡蛋至少有多少个. using System; ...
- 搭服务器之centos-ipv6源--配置各虚拟机系统的ipv6网络安装源。
在2g内存的台式机里安装了三台虚拟机,跑起来好可以,就是swap用的比较多,图见上一篇随笔.现在平台基本有了,自己笔记本算总控,实验室台式机跑着4台机器(一实三虚),加上一台服务器,可以做很多事情了, ...
- 强化学习实战 | 自定义Gym环境之扫雷
开始之前 先考虑几个问题: Q1:如何展开无雷区? Q2:如何计算格子的提示数? Q3:如何表示扫雷游戏的状态? A1:可以使用递归函数,或是堆栈. A2:一般的做法是,需要打开某格子时,再去统计周围 ...
- K8s PV and PVC and StorageClass
PVC和PV之间没有依靠ID.名称或者label匹配,而是靠容量和访问模式,PVC的容量和访问模式需要是某个PV的子集才能自动匹配上.注意:PVC和PV是一对一的,也即一个PV被一个PVC自动匹配后, ...
- Android开发-页面绘制
今天主要绘制了记账页面 记账页面用到的布局是TableLayout加Viewpager联动的方式,通过设置一个标题头可以实现页面的左右滑动,viewpager中添加两个fragment. 需要制作两个 ...
- React之react-router(connected-react-router/react-router-dom)
文档: react-router-dom官方文档:https://reacttraining.com/react-router/web/guides/quick-start connected-rea ...