============================================================================
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. learning to generate question headlines 讲座

    渣排版预警! 出发点 新闻用户为什么会点: 主观:用户兴趣/热点事件 客观:新闻标题(新闻入口)/新闻内容(更简单,更有趣) 标题分类: surprise,好奇,负例,数字,你,客观的描述,问题的形式 ...

  2. Python之函数第三篇

    一.匿名函数 匿名函数是lambda定义的没有名字的具有一些小功能的函数 具体形式是 lambda x: X**2 # 求平方操作 lambda x: x>100 # 判断参数是否大于100 二 ...

  3. Redis的快照持久化-RDB与AOF

    Redis持久化功能 Redis为了内部数据的安全考虑,会把本身的数据以文件形式保存到硬盘中一份,在服务器重启之后会自动把硬盘的数据恢复到内存(redis)的里边. 数据保存到硬盘的过程就称为“持久化 ...

  4. 异常处理汇总 ~ 修正果带着你的Code飞奔吧!

    异常处理汇总-运维系列 http://www.cnblogs.com/dunitian/p/4522983.html 异常处理汇总-开发工具  http://www.cnblogs.com/dunit ...

  5. MySQL匹配指定字符串的查询

    MySQL匹配指定字符串的查询 使用正则表达式查询时,正则表达式可以匹配字符串.当表中的记录包含这个字符串时,就可以将该记录查询出来.如果指定多个字符串时,需要用“|”符号隔开,只要匹配这些字符串中的 ...

  6. getParameter() getInputStream()和getReader() 区别 这三种方法是有冲突的,因为流只能被读一次。

    我们经常用servlet和jsp, 经常用request.getParameter() 来得到数据. request.getParameter()request.getInputStream()req ...

  7. 关于 IIS7.0下文件写入无权限的解决办法

    1. 在IIS Web站点上右键 --> 编辑权限 2. 在弹出的窗体上选择[安全]选项卡,如图: 3. 在安全选项卡中点击[编辑]按钮,弹出如图对话框: 4. 点击[添加]按钮,弹出如图对话框 ...

  8. iOS 内购讲解

    一.总说内购的内容 1.协议.税务和银行业务 信息填写 2.内购商品的添加 3.添加沙盒测试账号 4.内购代码的具体实现 5.内购的注意事项 二.协议.税务和银行业务 信息填写 2.1.协议.税务和银 ...

  9. java.lang.IllegalStateException: Cannot run without an instance id.

    启动springboot,报错:quartz集群报错: Sep 09, 2016 5:33:47 AM org.apache.catalina.core.ApplicationContext log ...

  10. 表表达式,Substring, CharIndex, 多行数据变同一行的用法

    参考: https://www.cnblogs.com/cnki/p/9561427.html https://www.cnblogs.com/johnwood/p/6386613.html 1.表1 ...