前言:

由于经常使用C++,但是又对C++内部机制不是很深入了解,所以看了一些关于C++的经典书籍,其中有《C++ Primer》、《STL源码剖析》、《Efficitive C++》、《More Efficitive C++》。《C++ Primer》特别适合刚使用C++的程序员学习,里面详细介绍了一些C++基础知识,包括流和STL容器、适配器、算法还有C++的面向对象的一些知识。这里主要介绍一些我看《深入探索C++对象模型》的一些理解。

对于面向对象(Object Oriented)语言,我们的疑惑就很多了。究其原因,这中语言的编译器为我们(程序员)做了很多我们不知道的服务:构造函数、析构函数、虚拟函数、继承、多态.......有时候它会为我们生成一些额外的函数,又有时候它会扩张我们所写函数的内容,放进更多的操作,还有时候它会为我们的object添油加醋,放一些奇妙的东西,使我们面对sizeof的结果大惊失色。

本书《深入探索C++对象模型》分为七章。

第1章,关于对象,提供以对象为基础的观念背景,以及由C++提供的面向对象程序设计典范。主要是对于对象模型的一个大略浏览,说明目前普及的工业产品,但没有对多重继承和虚拟继承有太靠近的观察。

第2章,构造语意学,介绍构造函数,构造函数何时被编译器合成,以及给程序带来的效率问题。

第3章,Data语意学,主要专注于各式各样的data member,详细介绍了data member的处理。

第4章,Function语意学,主要专注于各式各样的member functions,详细介绍了vitual functions。

第5章,构造、析构、拷贝语意学,讨论了如何支持class模型,也讨论了object的生命周期。

第6章,执行期语意学,检视执行期的某些对象模型行为,包括临时对象的生命机器死亡,以及对new运算符和delete运算符的支持。

第7章,在对象模型的尖端,专注于exception handling、template support、runtime type indentification。

1、什么是对象模型

(1)语言中直接支持面向对象程序设计的部分

(2)对于各种支持的底层实现机制

C与C++的区别,C语言中是将“数据”和“处理数据的操作(函数)”分离开来的,语言本身没有支持“数据和函数”之间的关联性,但是在C++中,却提供了一种ADT,它将“数据”和“ 处理数据的操作(函数)”结合起来,加入了class关键字。

考虑C++加上封装之后是否会产生布局成本,答案是:否!实际上,在C++中class就像C的struct的情况一样,member functions虽然含在class声明之内,却不出现在object之中,每一个non_inline member function只会诞生一个函数实体。至于每一个“拥有零个或一个定义”的inline function则会在其每一个使用者身上产生一个函数实体。这一个并未带给它任何空间或执行期的不良回应。C++在布局以及存取时间上主要的额外负担是由vitual引起,包括:vir1function机制、vitrtual base class。

2、C++对象模式

在C++中,有两种class data member:static和nonstatic,以及三种class member functions:static、nonstatic和virtual。C++对象模型有三种:(1)简单对象模型(A Simple Object Model)

图1 简单对象模型

在简单模型中,members本身并不放在object之中。只有“指向member的指针”采放在object内。这么做可以避免“member有不同的类型,因而需要不同的存储空间”所招致的问题。但是这个模型并没有并运用与实际产品上,不过关于索引或solt数目的观念,倒是被运用到C++的“指向成员的指针”(Pointer-to-member)观念之中。

表格驱动对象模型(A Table-driven Object Model):为了对所有class的所有objects都有一致的表达方式,表格对象模型是将所有与members相关的信息抽出来,放在一个data member table和一个member function table之中,class object本身则内含指向这两个表格的指针。Member function table是一系列的solts,每一个solt指出一个member function;Data member table则直接含有data本身。               

图2 表格对象驱动模型

表格对象驱动模型也没有实际运用于真正的C++编译器上,但member function table这个观念却成为支持visual functions的一个有效方案。

C++对象模型:可以说C++对象模型是继承了简单对象模型和表格驱动模型的两者的优点。它是从简单对象模型派生而来的,并对内存空间和存取时间做了优化。在模型中,Nonstatic data member被配置于每一个class object之内,static data member则被存放在所有的class object之外,static和Nonstatic function members也被放在所有的class object之外。Visual functions则以两个步骤支持之:

(1)每一个class产生一堆指向visual functions的指针,放在表格之中。这个表格称为visual table(vtbl)。(这种思想是从表格驱动模型中继承而来的)。

(2)每一个class object被添加了一个指针,指向相关的visual table(虚函数表)。通常这个指针称为vptr。vptr的设定和充值均由每一个class的constructor,destructor和copy assignment运算符自动完成。每一个class所关联的type_info object也经由visual table指出来,通常放在表格的第一个solt处。    

图3 C++对象模型

这个模型主要优点在于它的空间和存取时间的效率;主要缺点:如果运用程序代码未曾改变,单所用的class objects的nonstatic data members有所修改,那么那些运用程序均得重新编译,关于这一个点,前面的双表格模型可以提供较大的弹性,但因为多提供了一层间接性,因此也付出了执行空间和效率两方面的代价。

3、C++继承

(1)单一继承

(2)多重继承

(3)虚拟继承

虚拟继承特点:base class不管在继承串链中派生多少次,永远只会有一个实体。

“简单对象模型”中,每一个base class可以被derived class object内的每一个solt指出,该solt内含base class object的地址。这种机制的主要缺点:间接性导致空间和存取时间上的额外负担,优点则是class object的大小不会因其base class的改变而受影响。

“base table模型”也就是表格驱动模型中,base class table被产生出来时,表格中的每一个solt内含一个相关的base class地址。主要缺点:由于间接性而导致空间和存取时间上的额外负担,优点则是在每一个class object中对于继承都有一致的表现方式:每一个class object都应该在某个固定的位置上安放一个base table指针,与base classes的大小或数目无关,第二个优点,不需要改变class object本身,就可以放大、缩小、或更改base class table。

4、struct与class区别

思想上的区别:struct关键词的使用实现的是C的数据萃取观念,而class关键词实现的是C++的ADT观念。C++原本不是必须需要class关键字,但是它的加入,体现了C++的封装和继承的哲学。

内存存放的区别:struct是按声明顺序来存放数据,故可以使用小技巧来实现一个可变大小的数组,但是C++中class内数据存储却不一定是与声明一致,如:base classes和derived classes的data members的布局并没有强制规定谁先谁后。

默认权限的却别:class默认权限为private,而struct的默认权限是public。

5、 对象的差异

C++程序设计模型直接支持三种programming paradigms(程序设计典范)。

(1)程序模型(procedural model):面向过程,如字符串处理,可以使用字符数组以及str*函数集。

(2)抽象数据类型模型(ADT):该模型所谓的“抽象”是和一组表达式(public接口)一起提供,而其运算定义隐而未明。如:string class。

(3)面向对象模型(object-oriented model):类和继承、多态等。其中C++有三种方法支持多态:1)经由一组隐含的转化操作。例如把一个derived class指针转化为一个指向其public base class指针。

2)经由visual function机制

3)经由dynamic_cast和typeid运算符。

6、多态机制

指针:指针的内存大小固定,在32位机器上占4个字节,在64位机器上占8个字节。转型(cast)(如:ZooAnimal  *px)其实是一种编译器指令。大部分情况下它并不会去真正影响一个指针的地址,它只影响“被指出之内存的大小和内容”的解释方式。

多态允许继一个抽象的public接口之后,封装相关的类型。所付出的代价就是额外的间接性——不论是在“内存的获得”或是在“类型的决断”上,C++通过class的pointers和references来支持多态,这种程序设计风格就称为“面向对象”。

结论:

C++哲学思想:面向对象,其中:封装、继承、多态是核心,为了实现封装引入class关键字,然后详细介绍了class和struct的区别,还介绍了C++对象模型,C++的多态机制,内存分配等。

参考文献:

[1] 侯捷 《深入探索C++对象模型》

《深入探索C++对象模型》之一相关推荐

  1. 【连载】高效程序员的45 个习惯(不断更新中。。。)

    高效程序员的45 个习惯 本书收集了成功人士在开发过程中的 45 个个人习惯.思想观念和方法,有助于开发人员在开发进程.编码工作.开发者态度.项目和团队管理,以及持续学习等 5 个领域改善其开发工作. ...

  2. 《高效程序员的45个习惯》之体会

    不知大家是否有这样的感觉,总有那么多国外的好东西因为名字翻译太烂被大家忽视或者被低端化,比如那部印度的经典影片<3 Idiots>,被本土化后成了<三傻大闹宝莱坞>,还有经典书 ...

  3. 《高效程序员的45个习惯》读后感

    为什么80%的码农都做不了架构师?>>>    感受 敏捷开发人员必读. 关于书名.从内容看来,原书名<Practices of an Agile Developer>比 ...

  4. 《高效程序员的45个习惯》-之三

    请您在阅读本文之前,先了解<高效程序员的45个习惯>-之二. 每一期都会涉及15个话题,用3期来列出这45个习惯,每次不贪多,贪精,大家如果有空,一定要细细品味这15个习惯. 注意:每一个 ...

  5. 《高效程序员的45个习惯》-末篇

    请您在阅读本文之前,先了解<高效程序员的45个习惯>-之三. 每一期都会涉及15个话题,用3期来列出这45个习惯,每次不贪多,贪精,大家如果有空,一定要细细品味这15个习惯. 注意:每一个 ...

  6. 《高效程序员的45个习惯》-之二

    请您在阅读本文之前,先了解<高效程序员的45个习惯>-之一. 每一期都会涉及15个话题,用3期来列出这45个习惯,每次不贪多,贪精,大家如果有空,一定要细细品味这15个习惯. 注意:每一个 ...

  7. 《高效程序员的45个习惯》-之一

    敏捷开发是当下最流行的开发方法,它采用的是一种以人为核心.迭代.循序渐进的开发思想,值得你关注和学习. 最近我就阅读了一本有关敏捷开发的书籍,<高效程序员的45个习惯>. 它以" ...

  8. Hunter的读《高效程序员的45个习惯》

    本文完全节选自<高效程序员的45个习惯> 第一章敏捷--高效软件开发之道 敏捷开发宣言: 个体和交互胜过过程和工具 可工作的软件胜过面面俱到的文档 客户协作胜过合同谈判 响应变化胜过遵循计 ...

  9. 读书笔记 -《高效程序员的45个习惯-敏捷开发修炼之道》

    <高效程序员的45个习惯-敏捷开发修炼之道> 一本2010年出版的书,当时敏捷还只是在国外开始流行,像我这种菜鸟级根本听都没听过.这次通读了这本书,受益良多,回顾自己的职业生涯,多是漫无目 ...

  10. 读书笔记之《高效程序员的45个习惯----敏捷开发之道》 摘录

    读书笔记之<高效程序员的45个习惯----敏捷开发之道>摘录 此次原创的意思是指这个文章中的内容是由笔者从<高效程序员的45个习惯----敏捷开发之道>书中摘录,而不是别人摘录 ...

最新文章

  1. Linux更新pip国内源
  2. 【斯坦福新课】CS234:强化学习
  3. Apache Thrift - java开发详解
  4. 以太坊区块和交易存储
  5. 轻松删除git本地创建的仓库
  6. 基于Java的全文索引
  7. 结构体:求最高分和最低分
  8. JS特效——鼠标跟随特效——动态背景线条跟随鼠标移动
  9. Weighted-Entropy-based Quantization for Deep Neural Networks 论文笔记
  10. Activity启动模式和FLAG、TASKAFFINITY
  11. JS弹窗确认Ajax封装方法
  12. 最大子序列和算法C语言,最大子序列和O(N)算法简单分析『神兽必读』
  13. HDU 4983 Goffi and GCD(数论)
  14. 无线遥控器应用在安防防盗中有怎样作用?
  15. Java学习笔记分享之Dubbo篇
  16. blender中常用快捷键的总结
  17. FMCW 雷达基本原理
  18. git merge冲突解决
  19. 算法导论—分治策略(C语言)
  20. Crazy Engine 3.0(又名盘古引擎)的技术特性

热门文章

  1. Nginx - 主要作用(功能)
  2. idea快捷键设置快速删除一行和代码智能提醒
  3. idea中设置python环境
  4. OPENCV多种模板匹配使用对比
  5. opencv3之截取静态图片的脸部区域
  6. 大神TP_运营大神解密“双十一零超卖”电商库存管理系统
  7. JavaScript Array对象用于定义数组
  8. flash 与动画:发光
  9. 基于均值滤波的非线性反锐化掩膜
  10. 学生网上考试报名系统的设计与实现