Effective C++ 笔记:条款 31 将编译关系降至最低
31 : Minimize compilation dependencies between files
1 这关乎C++的类(或说都是类惹的祸)
1.1 C++类定义式的问题
C++类定义式不只叙述了class接口,还包括十足的实现细目。将导致编译依存关系(compilation dependency),更严重的将导致 连串编译依存关系(cascading compilation dependencies),会对许多项目造成难以形容的灾难。
通常是指类的内部成员,解决方法有两种
1.1.1 pimpl idiom设计(pointer to the implementation)
pimpl idiom pattern:
// handle class
class Person {
...
private:
std::tr1::shared_ptr<PersonImpl> pImpl; // 指向实物
};
1.1.2 虚基类(常用的接口设计)
// interface class
略
这是一个“将对象实现细目隐藏于一个指针背后”的游戏。
1.2 错误的前置声明
考虑以下代码:
namespace std {
class string; // 并不正确
}
原因:string是一个typedef,定义为basic_string< char >
通常情况下不需要对标准库进行前置声明,但要注意避免使用标准库程序中的“引发不受欢迎之#include”。
1 如果使用object references或object pointers可以完成任务,就不要使用objects。
你可以只靠一个类型声明式就定义出指向该类型的references和pointers;但如果定义某类型的objects ,就需要用到该类型的定义式。
2 如果能够,尽量以class声明式替换class定义式
class Date;
Date foo( Date d );
// 作为返回值、函数参数、没有任何问题。
// 当然pass-by-value是个糟糕的主意。疑问:为什么?是因为函数签名或者说函数声明的原因吗?
3 为声明式和定义式提供不同的头文件
// 同上
#include "datefwd.h"
// 参考标准库<iosfwd>(见条款54)
Date foo( Date d );它分外彰显本条款适用于模版与非模版。有些环境允许模版的实现与声明分离,那就可以提供一份只包含声明的头文件。同时有一个叫做export的关键字可实现模版的这一性质,有必要关心这一关键字的发展。
2 总结
2.1 犬儒学派的质疑
“将对象实现细目隐藏于一个指针背后”的游戏,很遗憾必须牺牲运行时的速度与空间。
2.2 抉择
那究竟何时应当使用“将对象实现细目隐藏于一个指针背后”这一手段与否?
程序发展过程中这两种方法以求实现代码有所变化时对其客户带来最小冲击。而当他们导致速度和/或大小差异过于重大以至于classes之间的耦合相形之下不成为关键时,就以具象类替换这两种方法。
请记住
1 一般构想是handle classes和interface class这两个手段。
2 程序库头文件应该以“完全且仅有声明式”(full and declaration-only forms)
专业词汇
compilation dependency
cascading compilation dependencies
precompiled headers
parasing
pipl idiom
handle classes
interface classes
concrete classes
full declaration-only forms
Effective C++ 笔记:条款 31 将编译关系降至最低的更多相关文章
- Effective C++ -----条款31:将文件间的编译依存关系降至最低
支持“编译依存性最小化”的一般构想是:相依于声明式,不要相依于定义式.基于此构想的两个手段是Handle classes 和 Interface classes. 程序库头文件应该以“完全且仅有声明式 ...
- 读书笔记_Effective_C++_条款三十一:将文件间的编译依存关系降至最低(第三部分)
下面来谈谈书中的第二部分,用Interface Classes来降低编译的依赖.从上面也可以看出,避免重编的诀窍就是保持头文件(接口)不变化,而保持接口不变化的诀窍就是不在里面声明编译器需要知道大小的 ...
- 条款31:将文件间的编译依存关系降至最低(Minimize compilation dependencies between files)
NOTE1: 1.支持“编译依存性最小化”的一般构想是:相依于声明式,不要相依于定义式.基于此构想的两个手段是Handle classes 和 Interface classes. 2.程序库头文件应 ...
- [Effective C++ --031]将文件间的编译依存关系降至最低
引言:编译时间成本 在项目中我们都会碰到修改既存类的情况:某个class实现文件做了些轻微改变,修改的不是接口,而是实现,而且只改private成分. 重新build这个程序,并预计只花数秒就好,当按 ...
- [Effective JavaScript 笔记]第31条:使用Object.getPrototypeOf函数而不要使用__proto__属性
ES5引入Object.getPrototypeOf函数作为获取对象原型的标准API,但由于之前的很多js引擎使用了一个特殊的__proto__属性来达到相同的目的.但有些浏览器并不支持这个__pro ...
- [EffectiveC++]item31:将文件间的编译依存关系降至最低
P143:“声明的依赖性"替换“定义的依存性”
- Effective C++笔记:实现
条款26:尽可能延后变量定义式的出现时间 博客地址:http://www.cnblogs.com/ronny/ 转载请注明出处! 有些对象,你可能过早的定义它,而在代码执行的过程中发生了导常,造成了开 ...
- Effective C++笔记 55条编程法则
1. 视C++为一个语言联邦 C++高效编程守则视状况而变化,取决于你使用C++的哪一部分. 2. 尽量以const,enum.inline替代#define 1) 对于单纯常量,最好以const ...
- Effective C++笔记05:实现
条款26:尽可能延后变量定义式的出现时间 博客地址:http://blog.csdn.net/cv_ronny 转载请注明出处! 有些对象,你可能过早的定义它,而在代码运行的过程中发生了导常,造成了開 ...
随机推荐
- Scala map与flatMap
1. map函数 对集合的每一个元素运用某个函数操作,然后将结果作为一个新的列表返回. 实例1:将列表中每个元素值乘以2 scala> val list1=List(1,2,3,4) lis ...
- Python笔记:深浅拷贝
1.赋值操作两者是同一数据,其内存地址一样.适用于list.dict.set数据类型. 2.copy是浅拷贝,只能拷贝嵌套数据的第一层数据,嵌套的数据与赋值操作相同,其内存地址一样,当一个被更改,其他 ...
- Java 身份证号码验证
身份证号码验证 1.号码的结构 公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成.排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码 2.地址码(前 ...
- py库:文本转为语音(pywin32、pyttsx)
http://blog.csdn.net/marksinoberg/article/details/52137547 Python 文本转语音 文本转为语音(使用Speech API) 需要安装 py ...
- logback的使用和logback.xml详解,在Spring项目中使用log打印日志
logback的使用和logback.xml详解 一.logback的介绍 Logback是由log4j创始人设计的另一个开源日志组件,官方网站: http://logback.qos.ch.它当前分 ...
- Signals的使用(通知)
https://docs.djangoproject.com/en/2.1/topics/signals/
- MySQL InnoDB内存压力判断以及存在的疑问
本文出处:http://www.cnblogs.com/wy123/p/7259866.html(保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误 ...
- Delphi TXLSReadWriteII 导出EXCEL
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- virsh命令详解
1.简介: virsh 有命令模式和交互模式如果直接在vrish后面添加参数是命令模式,如果直接写virsh,就会进入交互模式. 2.命令模式: virsh list 列出所有的虚拟机,虚拟机的 ...
- MongoError: no primary found in replicaset
nodejs连接mongodb时,使用集群方式报错 2017-09-22T01:42:32.115Z - error: db connect failed 2017-09-22T01:42:32.12 ...