《深度探索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++对象模型>正适合你 作者简介 ...
随机推荐
- vue部署服务器以及解决部署到apache路由出现404
最近在开发cms的时候使用Vue.js框架,利用vue-route.vue-cli结合webpack编写了一个单页路由项目,自己在服务器端配置apache.部署完成后,访问没问题,从页面中点击跳转就会 ...
- Educational Codeforces Round 117 (Rated for Div. 2)
Educational Codeforces Round 117 (Rated for Div. 2) A. Distance https://codeforces.com/contest/1612/ ...
- Kube-OVN1.5.0新版本发布,支持鲲鹏云平台网络平面部署
近日,Kube-OVN发布了最新的1.5.0版本.自2019年4月开源以来,Kube-OVN经历了15次重要版本迭代,以及社区成立,建设者贡献代码,稳定性测试,国内外用户开始在生产环境中投入使用,企业 ...
- 封装OCX
封装OCX的办法有2种: 1. 使用C++的MFC activex项目生成OCX 2. 使用C#的用户控件生成OCX(.net core好像不支持) 注意:以管理员身份运行Visual Studio ...
- git文件管理与索引,深入理解工作原理
前言 这一夜,注定是个不眠之夜,小白和cangls的对话已然进入了白热化.小白孜孜不倦的咨询关于git方面的知识,对索引越来越感兴趣.小白以前存的小电影文件可以进行版本的对比,探索哪个版本画质更好. ...
- 【解决了一个小问题】gin框架中出现如下错误:"[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 500"
POST到数据到一条gin框架的接口后,客户端收到400错误,并且返回了业务中返回的"decode json fail". 关键代码是: func report(c *gin.Co ...
- mate10碎屏机当成小电脑使用尝试
1.屏碎了修起来300-400,自己动手至少也要260以上买个屏幕钱. 手机图案锁屏也不知道密码,给我手机的亲戚忘了.当年手机被车压弯了. 对着恢复教程,盲屏幕猜着按还原了. 2.之后一路从8代系统更 ...
- 什么是以特性为核心的持续交付|阿里巴巴DevOps实践指南
编者按:本文源自阿里云云效团队出品的<阿里巴巴DevOps实践指南>,扫描上方二维码或前往:https://developer.aliyun.com/topic/devops,下载完整版电 ...
- 学习JAVAWEB第三天
## 数据库的设计· 1. 多表之间的关系 1. 分类: 1. 一对一(了解): * 如:人和身份证 * 分析:一个人只有一个身份证,一个身份证只能对应一个人 2. 一对多(多对一): * 如:部门和 ...
- Lesson8——Pandas reindex重置索引
pandas目录 1 简介 重置索引(reindex)可以更改原 DataFrame 的行标签或列标签,并使更改后的行.列标签与 DataFrame 中的数据逐一匹配.通过重置索引操作,您可以完成对现 ...