下面来谈谈书中的第二部分,用Interface Classes来降低编译的依赖.从上面也可以看出,避免重编的诀窍就是保持头文件(接口)不变化,而保持接口不变化的诀窍就是不在里面声明编译器需要知道大小的变量,Handler Classes的处理就是把变量换成变量的地址(指针),头文件只有class xxx的声明,而在cpp里面才包含xxx的头文件.Interface Classes则是利用继承关系和多态的特性,在父类里面只包含成员方法(成员函数),而没有成员变量,像这样: // Person.h…
引言:编译时间成本 在项目中我们都会碰到修改既存类的情况:某个class实现文件做了些轻微改变,修改的不是接口,而是实现,而且只改private成分. 重新build这个程序,并预计只花数秒就好,当按下“Build”,结果整个世界都被重新编译和链接了! 问题是在c++并没有把“将接口从实现中分离”做得很好.class 的定义式不只详细叙述了class接口,还包括十足的实现细目: 例如: class Person{ public: Person(const std::string& name, c…
支持“编译依存性最小化”的一般构想是:相依于声明式,不要相依于定义式.基于此构想的两个手段是Handle classes 和 Interface classes. 程序库头文件应该以“完全且仅有声明式”(full and declaration-only forms)的形式存在.这种做法不论是否涉及templates都适用.…
NOTE1: 1.支持“编译依存性最小化”的一般构想是:相依于声明式,不要相依于定义式.基于此构想的两个手段是Handle classes 和 Interface classes. 2.程序库头文件应该以“完全且仅有声明式”(full and declaration-only forms)的形式存在.这种不论是否涉及templates都适用.…
P143:“声明的依赖性"替换“定义的依存性”…
1. 牵一发而动全身 现在开始进入你的C++程序,你对你的类实现做了一个很小的改动.注意,不是接口,只是实现:一个私有的stuff.然后你需要rebuild你的程序,计算着这个build应该几秒钟就足够了.毕竟,只修改了一个类.你点击了build 或者输入了make( 或者其他方式),你被惊到了,然后羞愧难当,因为你意识到整个世界都被重新编译和重新链接了!当这些发生时你不觉的感到愤恨么? 2. 编译依赖是如何发生的 问题出在C++并不擅长将接口从实现中分离出来.类定义不仅指定了类的接口也同时指定…
inline函数 inline函数可以不受函数调用所带来的额外开销,编译器也会优化这些不含函数调用的代码,但是我们不能滥用Inline函数,如果程序中的每个函数都替换为inline函数那么生成的目标文件会急剧增加,当我们运行这个程序时会占用机器大量的内存,所以我们一般把本体很小的函数替换为Inline(一般10行以内). inline只是对编译器的申请,并不是强制执行,比方在class定义式内定义成员函数,如下所示 class Person { public: ... int age() con…
31 : Minimize compilation dependencies between files 1 这关乎C++的类(或说都是类惹的祸) 1.1 C++类定义式的问题 C++类定义式不只叙述了class接口,还包括十足的实现细目.将导致编译依存关系(compilation dependency),更严重的将导致 连串编译依存关系(cascading compilation dependencies),会对许多项目造成难以形容的灾难. 通常是指类的内部成员,解决方法有两种 1.1.1 p…
严肃对待编译器发出的警告信息.努力在你的编译器的最高(最严苛)警告级别下争取“无任何警告”的荣誉. 不要过度依赖编译器的报警能力,因为不同的编译器对待事情的态度并不相同.一旦移植到另一个编译器上,你元本年依赖的警告信息有可能消失.…
(这里的验证结果是针对返回值优化的,其实和条款22本身所说的,考虑以操作符复合形式(op=)取代其独身形式(op),关系不大.书生注) 在[More Effective C++]条款22的最后,在返回值的返回方式上,大师Meyers推荐使用表达式[returnT(lhs)+=rhs;]这种使用匿名临时变量的方式,理由是“自古以来未具名对象总是比具名对象更容易被消除”,这种写法将更好地帮助编译器实现返回值优化(ReturnValue Optimization,简写RVO). 针对上述说法,我在两款…