《深度探索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++对象模型>正适合你 作者简介 ...
随机推荐
- springboot集成oss阿里云存储
一.注册阿里云 二.购买OSS 三.创建桶 设定权限,其它默认即可 四.创建目录 点击桶名,进入创建目录即可. 五.开发文档 引入依赖: <dependency> <groupId& ...
- Android官方文档翻译 十七 4.1Starting an Activity
Starting an Activity 开启一个Activity This lesson teaches you to 这节课教给你 Understand the Lifecycle Callbac ...
- flume安装及使用
最近在学习hadoop大数据平台,但是却感觉无从下手,于是看了一些专业的书籍,觉得还是先从下往上为学习也就是从源数据--数据抽取--存储--计算--展示这个路线来学习比较容易一些,所以就先从非结构化数 ...
- 《剑指offer》面试题17. 打印从1到最大的n位数
问题描述 输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数.比如输入 3,则打印出 1.2.3 一直到最大的 3 位数 999. 示例 1: 输入: n = 1 输出: [1,2,3,4,5 ...
- 【刷题-PAT】A1108 Finding Average (20 分)
1108 Finding Average (20 分) The basic task is simple: given N real numbers, you are supposed to calc ...
- ROS之arduino交互
一.第一种安装方式(不支持自定义消息) 第一步打开官网 http://wiki.ros.org/rosserial_arduino/Tutorials/Arduino%20IDE%20Setup 第二 ...
- Cesium入门7 - Adding Terrain - 添加地形
Cesium入门7 - Adding Terrain - 添加地形 Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com ...
- 学习OAuth 2.0
认识OAuth 2.0 OAuth 2.0 是行业标准的授权协议. OAuth 2.0 专注于客户端开发人员的简单性,同时为 Web 应用程序.桌面应用程序.移动设备提供特定的授权流程. 应用场景 有 ...
- qt 简单登录界面(一)
widget.h #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include<QLineEdit> class ...
- SpingMVC注解式开发-处理器方法的参数(形参request等)
HttpServletRequest HttpServletResponse HttpSession 请求中所携带的请求参数