============================================================================
5-0. 一般而言,class 的data member 应该被初始化,并且只在constructor中是在class 的其他member functions 中指定初值。其他任何操作都将破坏封装性质,是class 的维护和修改更加困难。


图片5-0;

(1)纯虚拟函数的存在
注:编译器不会在扩展derived class 的destructor时停止对pure Virtual destructor的调用操作(因为class设计者可能真的定义了一个pure Virtual destructor);编译器也不会自己取合成一个pure Virtual destructor的函数定义(编译器没有足够的知识,因为编译器对一个可执行文件采取“分离编译模型”)。
一个比较好的替代方案就是,不要把Virtual destructor 声明为pure。

(2)虚拟规格的存在
一般而言,把所有的成员函数都声明为Virtual function,然后再靠编译器的优化操作把非必要的Virtual invocation 去除,并不是好的设计观念。

(3)虚拟规格中const的存在
不把函数声明为const,意味着该函数不能够获得一个const reference 或 const pointer。比较令人头大的是,声明一个函数为const,然后才发现其derived instance 必须修改某一个data member。简单想法:不再用const就是了。

(4)重新考虑class 的声明


图片5-0-1;

============================================================================
5-1. “无继承”情况下的对象构造


图片5-1-1;

(1)抽象数据类型
如果要对class 中的所有成员都设定常量初值,那么给予一个explicit initialization list 会比较高效(比起意义相同的constructor 的 inline expansion(内联扩展)而言)。甚至在local scope中也是如此。


图片5-1-2;

观念上,我们的Point class 有一个相关的default copy constructor、copy operator和destructor,然而它们都是无关痛痒的,而且编译器实际上根本没有产生它们。

(2)为继承做准备
继承下的多态决议,Virtual functions的引入,每一个class object 多负担一个vptr,并且也引发编译器对于我们的class 产生膨胀作用:


图片5-1-3;

注:C++ Standard 要求编译器尽量延迟 nontrivial members 的实际合成操作,直到真正遇到其使用场合为止。

============================================================================
5-2. 继承体系下的对象构造


图片5-2-1;


图片5-2-2;

(1)虚拟继承
问题:对于Virtual base class 的构造,由更往后(往下)的继承来负责“被共享之virtual base class(派生类的subobject)”的构造。
添加条件测试:只有一个完整的class object 被定义出来时,它才会被调用;如果object只是某个完整object 的subobject,它就不会被调用。

(2)vptr初始化语意学
如下的继承体系:


图片5-2-3;


图片5-2-4;


图片5-2-5;


图片5-2-6;

然而,这个看似完美的解决有关限制虚拟机制的问题,却仍不完美:

图片5-2-7;


图片5-2-8;

============================================================================
5-3. 对象复制语意学


图片5-3-1;


图片5-3-2;


图片5-3-3;

注:书中作者建议,尽可能不要允许一个virtual base class 的拷贝操作。甚至:不要在任何virtual base class 中声明数据。

============================================================================
5-5. 解构语意学


图片5-5-1;


图片5-5-2;


图片5-5-3;

============================================================================

Inside The C++ Object Model(五)的更多相关文章

  1. C++学习书籍推荐《Inside the C++ Object Model》下载

    百度云及其他网盘下载地址:点我 作者简介 Stanley B. Lippman is Architect with the Visual C++ development team at Microso ...

  2. inside the C++ Object model总结

    一. 关于对象 1.内联函数:能够除去函数调用的开支,每一处内联函数的调用都是代码的复制.这是一种空间换取时间的做法,若函数代码量大或者有循环的情况下,不宜内联(这件事有些编译器会自动帮你做).在类中 ...

  3. 《深度探索C++对象模型(Inside The C++ Object Model )》学习笔记

    转载:http://dsqiu.iteye.com/blog/1669614 第一章 关于对象 使用class封装之后的布局成本: class并没有增加成本,data members直接内含在每一个c ...

  4. Inside The C++ Object Model - 03

    object Lessons 1.C++中布局以及存取时间上的的额外负担是由virtual引起的:virtual function.virtual base class.或是由于多继承引起的. 2.C ...

  5. Inside The C++ Object Model(四)

    ============================================================================4-1. Member 的各种调用方式静态成员函 ...

  6. Inside The C++ Object Model(三)

    ============================================================================3-0. 类所占的内存大小受到三个因素的影响:( ...

  7. Inside The C++ Object Model(二)

    ============================================================================2-0. 关键字explicit被引入C++,提 ...

  8. Inside The C++ Object Model(一)

    ============================================================================1-1. 关键字struct和class的一点区 ...

  9. Inside The C++ Object Model - 04 C++对象模型的一个简单示例

    首先定义一个类X class X { public: X(); X(const X& x); virtual ~X(); virtual foo(); } 再来一段代码: X foobar() ...

随机推荐

  1. 学习Struts--Chap04:result中type属性dispatcher、redirect、redirectAction、chain的区别

    1.Struts2框架中常用的结果类型的分析和比较 dispatcher:缺省的result类型,type默认是dispatcher内部转发.如果不写type类型只写一个名字的话,不单是type类型默 ...

  2. Error: Invalid or corrupt jarfile

    使用IDEA通过MAVEN创建quickstart项目后,添加了Artifacts,发现生成的jar包无法run,出现下面的错误: Error: Invalid or corrupt jarfile ...

  3. java解决手机上传竖拍照片旋转90\180\270度问题

    <dependency> <groupId>com.drewnoakes</groupId> <artifactId>metadata-extracto ...

  4. Xposed 框架 hook 简介 原理 案例 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  5. Swagger Annotation 详解(建议收藏)

    转载:https://www.jianshu.com/p/b0b19368e4a8 在软件开发行业,管理文档是件头疼的事.不是文档难于撰写,而是文档难于维护,因为需求与代码会经常变动,尤其在采用敏捷软 ...

  6. C# 之 批量插入数据到 SQLServer 中

    创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的是GUID,表中没有创建任何索引.GUID必然是比自增长要快.而如果存在索引的情况下,每次插入记录都会进行索引重建,这是非常耗性能的.如 ...

  7. ionic 状态栏显示异常 statusBar

    从主分支上新建一个分支开发另一个app, 生成之后手机上显示状态栏异常, 如下图, 只显示了电池的色块, 百思不得其解啊. 各种猜测无果, 对比config.xml, 发现statusBar插件版本不 ...

  8. Vue $emit()不触发方法的原因

    vue使用$emit时,父组件无法触发监听事件的原因是: $emit传入的事件名称只能使用小写,不能使用大写的驼峰规则命名

  9. Linux 系统 TCP优化

    这里主要是对<High performance Browser Networking>一书中关于TCP的描述的整理,本书与2013年出版,在书出版后,内核做了一些升级,有可能某些项不再适用 ...

  10. fastcgi php-cgi与php-fpm区别和之间的关系

    关于FastCGI.php-cgi.php-fpm的区别是什么,各自有什么用途,以及相互间的关系是什么,查阅相关资料,可谓是众说纷纭,莫衷一是: 说法一:fastcgi是一个协议,php-fpm实现了 ...