引言

  以前读《C++ Primer》的时候一直有一种感觉:该书虽然是C++入门书籍,初学者读之却觉晦涩,越往后读越是如此。等到稍加理解后再读该书,顿感醍醐灌顶,茅塞顿开。究其原因,在于原作者Stanley Lippman总是会有意无意地从编译器的角度来介绍语言的细节:对新手而言,哪里会去关注这样底层的实现呢?

  当读到《Inside The C++ Object Model》时,上述感觉愈发强烈,两书之间渐进讲述的细节让人读后大呼过瘾,也深感大师级作者笔触间的睿智。

  众所周知,C++是一门支持多范式的语言(《Effective C++》Item1),其中最为重要,对C语言最大的变革便是面向对象的设计思想。而本书,依其简介,探索“对象导向程序所支持的C++对象模型”下的程序行为。对于“对象导向性质之基础实现技术”以及“各种性质背后的隐含利益交换”提供一个清楚的认识。检验由程序变形所带来的效率冲击。提供对象导向观念和底层对象模型之间的效率测量。

关于对象

  从C语言转化到C++时,一个显而易见的区别在于从全局数据过渡到数据封装,那么其布局成本(Layout Costs)如何?答案是并未增加。本文后续将讲述C++在布局以及存取时间上主要的额外负担是由virtual引起,包括:

  • virtual function 机制,用来支持有效率的“执行期绑定”。
  • virtual base class 虚基类机制,以实现共享虚基类的 subobject。

  此外还有一些多重继承的额外负担,除此,C++毫无理由比C慢。

C++对象模式

  类的成员包括类数据成员(静态和非静态)和类成员函数(静态,非静态和虚函数)。

  考虑如下简单对象模型:

  我们看到,成员本身并不在对象里,只有指向对象的指针才在,如此可以避免成员因类型不同而导致存储空间不同。显然,成员以每个slot的索引值来寻址。

  考虑表格驱动对象模型(见上中图1.2):

  该方案中,把所有成员分离放在数据成员表和成员函数表两个表中。类对象则含有指向这两个表的指针。

  遗憾的是,以上两种方案都没有真正应用于C++编译器中,但它们的设计思想,或多或少被有所继承。

  来看C++对象模型的实现(见上右图1.3):

  在该模型中,非静态数据成员放在类对象中,静态数据成员则放在类对象外;静态和非静态函数成员也放在类对象外;虚函数以下步骤支持:

  • 用一个虚函数表(VTBL)记录指向虚函数的指针;
  • 类对象则以一个指针(VPTR)指向虚函数表,vptr操纵由类的复制控制完成。
  • 类所关联的type_info object由虚函数表指出,位于第一个slot处。

  该模型的优点在于空间和存取时间的效率,主要缺点在于非静态数据成员修改时必须重新编译。

加上继承

  在虚拟继承的情况下,基类不管被派生多少次,都只有一个实体(subobject)。C++最初的继承模型不运用任何间接性:基类实体的数据成员被直接放在派生类对象中。后来又引入虚基类,则通过一些间接的基类表现方法。具体实现本文不做阐述,留待后续博文。

对象的差异

  C++程序设计模型直接支持三种程序设计典范:

  1.程序模型:即来自C语言的部分;

  2.抽象数据类型模型:即封装与抽象;

  3.面向对象模型:定义基类并派生出子类。

  记住,纯粹以一种典范写程序,有利于整体行为的良好稳固。

多态

  C++以下列方法支持多态:

  1.隐含的转化操作:把派生类的引用/指针转化为基类的引用/指针;

  2.虚函数机制:动态绑定;

  3.dynamic_cast和typeid运算符。

  那么,需要多少内存才能表现一个类对象呢?

  • 其非静态数据成员的总和大小;
  • 加上由译注的需求而填补上去的空间;
  • 加上为了支持virtual而产生的负担(例如:指向虚函数表的指针的大小)。

  

转载于:https://www.cnblogs.com/huashu/p/4339690.html

深度探索C++对象模型——关于对象相关推荐

  1. 深度探索C++ 对象模型(2)-类的对象的内存大小_2

    继续上文,看看继承类的大小 1. Bear类 类对象的大小为24: 16+8 class Bear : public ZooAnimal { public:Bear() {};~Bear() {}; ...

  2. 深度探索C++ 对象模型(2)-类的对象的内存大小

    1. Question: 32bit机器 1个指向地址1000的指针的大小是多少? 指针类型 涵盖地址空间 整数指针 1000~1003(32bit整数是4-bytes) void*指针 不确定 2. ...

  3. 《深度探索C++对象模型》--5 构造析构拷贝 6 执行期语意学

     <深度探索C++对象模型>--5构造.析构.拷贝语意学 1.纯虚函数: (1)C++可以定义和调用一个纯虚函数,不过只可以静态调用,不可以由虚拟机制调用. 注意:pure virtu ...

  4. 深度探索C++ 对象模型(7)-Data member的布局(无继承、继承无多态、继承多态、多层继承)

    无继承 继承无多态 继承多态 虚表 : 用来存放基类的每一个虚函数,再加上首位的一个slots(支持RTTI). 每个class object导入一个vptr,提供执行期的链接,使得每一个class ...

  5. 深度探索C++ 对象模型(5)-Initialization list(2)

    Initialization list的作用是效率 如下代码可以编译并运行,但是效率低下 class Word {String _name;int _cnt;public:Word() { _name ...

  6. 深度探索C++ 对象模型(5)-Initialization list(1)

    以下四种情况,一定要使用成员初始化列表: 1.初始化一个引用成员 2.初始化一个const成员 示例代码为 class Shape{const int m_size; //const 常量int &a ...

  7. 深度探索C++ 对象模型(4)-Default Copy Constructor(2)

    没有Default Constructor, class Myclass{ public://... private:int a;char *str; }; 编译器执行的是"位逐次拷贝(Bi ...

  8. 深度探索C++ 对象模型(3)-默认构造函数Default Constructor

    1. Default Constructor只对base class subobjects和member class objects初始化,对data member不做操作 2. 编译器构造Defau ...

  9. 深度探索C++ 对象模型(1)-三种对象模型的设计

    1.类的成员 数据成员 . Static . Nonstatic 成员函数 . Static . Nonstatic . virtual Questions: C++封装带来的布局成本是多大? 由空类 ...

最新文章

  1. 边缘计算不再“边缘”
  2. 【转】iOS开发24:使用SQLite3存储和读取数据
  3. matlab 计算误码率,关于误码率的问题 急!!!!!
  4. java教程pdf下载百度云,面试题+笔记+项目实战
  5. ubuntu系统下Jenkins和tomcat的安装与配置
  6. android 4.0系统,全新Android 4.0系统_手机Android频道-中关村在线
  7. 算法--生成1~n的排列
  8. 01-01 Linux系统与shell环境准备
  9. oracle dba 两日速成课程.pdf,oracle_dba_两日速成课程.pdf
  10. 【MyBatis】缓存配置
  11. 正定矩阵与半正定矩阵定义性质与理解
  12. 计算机网络对大学生负面影响案例,大学生网络成瘾问题的危害及影响
  13. Scanport(转来备用,在那小子以后攻击我的时候用)
  14. 深度长文探讨Join运算的简化和提速
  15. 数字信号处理--语音信号变声报告
  16. 2021-07-16芯片-全球半导体产业核心地区的补贴及激励措施
  17. 笔记:关于Google Play这个应用市场app signing的坑
  18. 人脸识别门禁的那些“坑”,你中招了吗?
  19. Elasticsearch7.x指定JDK及安装时报错
  20. HTML中引入CSS文件的几种方法

热门文章

  1. 2019牛客暑期多校训练营(第五场)F - maximum clique 1 (最大团:补图最大独立集)
  2. stringiostream的用法
  3. kafka 出现Java heap space的解决方法
  4. c++迭代器的一个例子
  5. centos 安装rar 和 unrar
  6. java中堆栈(stack)和堆(heap)
  7. 查看dll文件被哪些软件调用的命令
  8. Hadoop基本流程与应用开发
  9. 跳一跳201803-1
  10. git删除远程服务的文件夹