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 将编译关系降至最低的更多相关文章

  1. Effective C++ -----条款31:将文件间的编译依存关系降至最低

    支持“编译依存性最小化”的一般构想是:相依于声明式,不要相依于定义式.基于此构想的两个手段是Handle classes 和 Interface classes. 程序库头文件应该以“完全且仅有声明式 ...

  2. 读书笔记_Effective_C++_条款三十一:将文件间的编译依存关系降至最低(第三部分)

    下面来谈谈书中的第二部分,用Interface Classes来降低编译的依赖.从上面也可以看出,避免重编的诀窍就是保持头文件(接口)不变化,而保持接口不变化的诀窍就是不在里面声明编译器需要知道大小的 ...

  3. 条款31:将文件间的编译依存关系降至最低(Minimize compilation dependencies between files)

    NOTE1: 1.支持“编译依存性最小化”的一般构想是:相依于声明式,不要相依于定义式.基于此构想的两个手段是Handle classes 和 Interface classes. 2.程序库头文件应 ...

  4. [Effective C++ --031]将文件间的编译依存关系降至最低

    引言:编译时间成本 在项目中我们都会碰到修改既存类的情况:某个class实现文件做了些轻微改变,修改的不是接口,而是实现,而且只改private成分. 重新build这个程序,并预计只花数秒就好,当按 ...

  5. [Effective JavaScript 笔记]第31条:使用Object.getPrototypeOf函数而不要使用__proto__属性

    ES5引入Object.getPrototypeOf函数作为获取对象原型的标准API,但由于之前的很多js引擎使用了一个特殊的__proto__属性来达到相同的目的.但有些浏览器并不支持这个__pro ...

  6. [EffectiveC++]item31:将文件间的编译依存关系降至最低

    P143:“声明的依赖性"替换“定义的依存性”

  7. Effective C++笔记:实现

    条款26:尽可能延后变量定义式的出现时间 博客地址:http://www.cnblogs.com/ronny/ 转载请注明出处! 有些对象,你可能过早的定义它,而在代码执行的过程中发生了导常,造成了开 ...

  8. Effective C++笔记 55条编程法则

    1.  视C++为一个语言联邦 C++高效编程守则视状况而变化,取决于你使用C++的哪一部分. 2.  尽量以const,enum.inline替代#define 1) 对于单纯常量,最好以const ...

  9. Effective C++笔记05:实现

    条款26:尽可能延后变量定义式的出现时间 博客地址:http://blog.csdn.net/cv_ronny 转载请注明出处! 有些对象,你可能过早的定义它,而在代码运行的过程中发生了导常,造成了開 ...

随机推荐

  1. LeetCode【100. 相同的树】

    看到这道题,第一思考是结构和节点完全相同 第一次,就没有思考null的情况 if(p.val == q.val && p.left.val == q.left.val &&am ...

  2. wordpress 解决文章内http链接问题

    1. 登录Wordpress后台, 常规设置  > 里面把站点URL 修改成 https开头 2. 登录phpmyadmin , 执行替换链接的SQL 替换wordpress配置的链接地址 (可 ...

  3. Java 详解 JVM 工作原理和流程

    Java 详解 JVM 工作原理和流程 作为一名Java使用者,掌握JVM的体系结构也是必须的.说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java ...

  4. C#设计模式(1)——单例模式(Singleton)

    单例模式即所谓的一个类只能有一个实例, 也就是类只能在内部实例一次,然后提供这一实例,外部无法对此类实例化. 单例模式的特点: 1.只能有一个实例: 2.只能自己创建自己的唯一实例: 3.必须给所有其 ...

  5. linux 查看任务运行时间

    ps -eo pid,tty,user,comm,lstart,etime | grep pid 15590 ? meicai java Wed Sep 26 20:04:31 2018 35-15: ...

  6. python 对象转字典

    从数据库中取出的数数据是 对象类型的,不能直接展示出来,需要转成字典类型,然后转成json 字符串,传给前端: data = {} data.update(obj.__dict__) print(da ...

  7. linux目录与文件权限的意义

    现在我们已经知道了Linux系统内文件的三种身份(所有者,用户者,与其他人),知道每种身份都有三种属性(r,w,x),已经能够使用chown,chgrp,chmod去修改这些权限和属性,那么这些文件权 ...

  8. python sqlparse 各种 token

    https://blog.csdn.net/qq_39607437/article/details/79620383 import sqlparse def look(statement): prin ...

  9. CSS 图像

    CSS 图像 <上一节下一节> 通过CSS可以控制图像的大小和对齐方式. 图像大小 虽然在HTML中,img标签有属性height.width设置高和宽,在工作中却使用得非常少,通常使用C ...

  10. 对于链表中tada的绝对值相等的点,仅保留第一次出现的结点而删除其余绝对值相等的点

    算法的核心思想是用空间换时间,使用辅助数组记录链表中已出现的数值  从而只需对链表进行一趟扫描 typedef struct node { int data; struct node* next; } ...