1. 用户将一个源文件提交给编译器后,首先进行的是该文件的预处理,也就是说,完成宏处理,并按照#include指令引进所有头文件。预处理之后的结果被称为编译单位。
2. 在一个由许多分别编译的部分组成的程序里,这些声明必须保持一致,就像在由一个编译单位组成的程序里,所有声明都必须一致一样。
3. 连接器是一个程序,它的工作就是将分别编译的部分约束在一起。
4. 连接工作可以在程序开始运行之前完全做好。另一种方式是允许在程序开始运行后为其加入新代码(动态链接)
5. 程序是由一些文件组成的,这种组织通常被称为程序的物理结构。
6. 所有名字空间,类,函数等都应该在它们出现的各个编译单位中有适当的声明,而且所有声明都应该一致的引用同一个实体,保证这一点是程序员的工作。
7. 如果定义在全局作用域或者名字空间作用域里某一个变量没有初始式,它就会被按照默认方式初始化。对局部变量和在自由存储中建立的对象而言,情况就不是这样。
8. 如果一个名字可以在与其定义所在的编译单位不同的地方使用,就说它是具有外部链接的。如果某个名字只能在其定义所在的编译单位内部使用,它就被称为是具有内部链接的。
9. 按照默认约定,const和typedef都具有内部链接
10. 通过显示声明,可以使const具有外部链接:extern const int a = 77;
11. 无名名字空间可以用于使一些名字局部于一个编译单位。无名名字空间的效果很像是内部链接。
12. 在c和c++程序里,关键字static也被用来表示使用内部链接
13. 许多现代c++实现都提供了对头文件的某种预编译形式,以尽可能减少反复编译同一个头文件所需要的工作。
14. 头文件里绝不应该有:常规的函数定义,数据定义,聚集量定义,无名名字空间,导出的模版定义。(注:无名名字空间内的定义多次引用会被认作重复定义,导出的模版定义应该是外连接的。)
15. 一个类,模版,或者在线函数的两个定义能够被接受为同一个唯一定义的实例,当且仅当:1)它们出现在不同的编译单位里;2)它们按一个个单词对应相同;3)这些单词的意义在两个编译单位中也完全一样。
16. 导出模版:如果只存在一个声明,就可以使用一个导出的模版:
//file1.c
export template<class T> T twice(T t) {return t+t;}
// file2.c
template<class T> T twice(T t);
int g(int i) { return twice(i);}
关键字export的意思就是在其它的编译单位里可以使用
17. 可以在一个extern声明中给出有关的链接约定
18. extern "C"指令描述的是一种链接约定,它并不影响调用函数的语义。
19. __cplusplus是一个预定义的宏名字
20. 通常很值得将实现方和用户方的界面区分开
21. 原则上说在所有函数之外定义的变量都应该在main()的调用之前完成初始化
22. 对于不同编译单位的全局变量,其初始化的顺序则没有任何保证。
23. 通过函数返回的引用可以作为全局变量的一种很好的替代物。
24. 非局部静态变量的初始化由具体实现中启动c++程序所用的机制控制,只有main()被执行,这一机制才能保证正确工作。因此,如果要将一段c++代码作为某个非c++程序的一部分去执行,我们就应该避免在其中定义需要运行中初始化的非局部变量。
25. 如果一程序利用标准库函数exit()终止,所有已经构造起来的静态对象的析构函数都将被调用。然而,如果程序使用标准库函数abort()而终止,那么析构函数就不会被调用。
26. 调用exit()结束程序,意味着调用它的函数及其调用者里的局部变量的析构函数都不会执行。
27. 抛出一个异常并捕捉它则能保证局部变量被正确的销毁。
28.