C++特性的臃肿:C++是一门包含大量高级特性的巨型语言。越高级,越有用,但是越难用,越容易出错,世上好多事情都说这样的。
所以不如我们先看看它是怎么处理的,很多事情,尤其是编程,我们一定要踩在别人铺就的路上才能前进,即使你是在发明一种新的语言。
保持统一编程风格意味着可以轻松根据“模式匹配”规则推断各种符号的含义。创建通用的、必需的习惯用语和模式可以使代码更加容易理解。
这点是显而易见的,和一个懂电脑的人讨论电脑的话题和与一个不懂电脑的人讨论用的词语一定是不一样的。如果对方理解你用的词语,甚至你们用的都是一样的词语,也就是专业术语,沟通就变得很简单了。
编程风格就是这个意思,至于将编程风格更加的框架化和统一化,就是设计模式专门讲得东西了。那二十几条都是成千上万次的摸爬滚打后编程人员总结出来的“编程风格”。
重申一遍,它只是一种编程风格,你不用它不会死人的,所以我看它的时候就只是想想,它到底有没有用,有用我就用,没用就拉倒。
头文件
当你刚开始编程的时候,你每次都是先include一个头文件iostream,它是和输入输出相关的,但是你并不知道它到底包含些什么,你也不想知道,只不过将它引过来而已。因为你急着要写下面的代码了。
但是当你编程编到一定程度后,你的老师很自然的就要求你将很多的头文件引用,函数声明放到一个头文件里,这时候你就不得不去理会这个头文件了。
接下来你将要遇到的问题就是作者提到的:
头文件里的东西是要被编译的,但是如果几个头文件之间互相包含,那么你调用几个头文件之后就会导致很多相同的内容被多次编译……
如果你用了一个很大的头文件的一个小函数,但是这个头文件的另一个小函数被修改了,那么你的代码就需要重新编译……
他们是这么做的:
对于第一个问题:所有头文件都应该使用#define防止头文件被多重包含,命名格式当是:<PROJECT>_<PATH>_<FILE>_H_
例如项目foo中的头文件foo/src/bar/baz.h按如下方式保护:
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif
就是说如果这个头文件没有被包含,那么就包含它。这个被称作卫哨或者头文件卫士或者什么,可能英文用的是guard,无所谓。
对于第二个问题:
宁可尽量少包含头文件,尤其是多重包含的情况。否则牵一发而动全身。
包含文件时提出了一个顺序,好象是有些道理的:
次序如下:C库、C++库、其他库的.h、项目内的.h,并且按照首字母排序。
文件的次序除了美观之外,最重要的是可以减少隐藏依赖,使每个头文件在“最需要编译的地方编译
头文件中还可以包含一种很特别的函数,内联函数。内联函数就是编译时会将函数体展开到调用处的函数,一般函数在被调用时总是要用到栈来保存参数和当前地址的,这要占用时间和内存。内联就是把代码都放到一起,顺序执行。但是又不像将代码都放在一起那么“难看”……
但是关于内联要记住:
当函数体比较小的时候,内联该函数可以令目标代码更加高效。至于函数要小到什么程度,3行,5行,10行,差不多就行。
当函数很大时,代码很多,或者是有循环,switch或者是递归,都不要用内联。很大的函数声明为内联,反而会增加代码量,弄巧成拙。
析构函数不要声明为内联,它们一般比你看到的代码要大得多。
虚函数和递归函数即使被声明为内联的也不一定就是内联函数。
定义函数时,参数顺序为:输入参数在前,输出参数在后
这一点实在是提不出什么理论依据,况且有的值是要被修改的,这说明它既是输入又是输出。但是我觉得却是这样规范是不错的,注意它至少它有助于你养成一定的编程风格。如果输入的值不被修改,那么前半部分的参数都声明为const &,后半部分都声明为 &或者指针,不是很一目了然?