c++ coding style
header file
Name and order of includes
顺序是
Related header, C library, C++ library, other libraries'.h, your project's
.h`.
不要使用 . 以及 .. 这样的符号
比如一个项目的include 头文件应该是这样
#include "foo/server/fooserver.h"
#include <sys/types.h>
#include <unistd.h>
#include <hash_map>
#include <vector>
#include "base/basictypes.h"
#include "base/commandlineflags.h"
#include "foo/server/bar.h"
class
Doing work in constructors
constructor 不能调用虚函数, 因为在构造的时候, 这个对象还没有完全生成, 因此调用虚函数肯定是不对的
Inheritance
使用 override 来表示某一个函数是virtual 函数的重新实现, 这样就不需要在看代码的时候确认这个函数是否是重载, 如果在子类里面对一个父类没有的函数进行override也是会直接报错的
在使用struct的时候 只用在只定义数据,不包含任何方法的结构体里面,出了简单的构造函数或者init函数.
通过使用继承可以有效的减少代码量 并且因为继承是编译时期的 因此在编译器能够识别这些错误 接口继承(也就是定义纯虚函数) 更是能够在编译期就识别一个继承的类是否实现了全部的接口
但是由于继承把一个类的代码分散在各个文件里面了 因此增加了看代码的难度 并且父类定义自己的成员变量 因此访问的时候不是很方便
所以一定要账号 is-a 和 has-a的关系 一定确定是 a是b的一种的时候才可以使 用 继承 否则尽可能的使用组合 也就是b里面有一个a的成员变量
Function
parameter Ordering
函数的变量的顺序: input, 然后是output
尽量把一个函数控制在40行以内
reference Arguments
所有通过引用传参的变量都需要加上const, 也就是 const type &in
尽可能的input argument 用value 或者 const reference(当然如果这个变量就是指针, 那么传进来的时候就用指针), 然后output argument 用指针
还有就是如果变量需要传进来NULL的时候, 可能会用const T*
function overloading
尽可能的不要使用 function overloading, 因为function overloading 增加了c++ 的复杂性. 特别是当继承的时候, 子类只实现了父类的某一个function 的时候, 这样代码的复杂度就更麻烦了. 因为不知道重载的是哪一个函数, 因此
尽可能的不要使用function overloading, 当遇到函数需要不用的变量类型的时候, 可以写成这种AppendString(), AppendInt() 这种
default value
允许在非non-virtual 函数里面使用 default value
scoping
Nonmember, static member, global function
如果有一个函数和一个类的对象里面的内容并不相关
那么这个时候有两个选择, 可以定义成class static member function, nonmember function. 那么这个时候如何选择?
如果这个函数和这个对象强相关, 比如是建立一个这个对象, 或者操作这个类的静态成员函数的时候, 将这个函数声明成class static member function
否则将这个函数声明成nonmember function, 然后用namespace 隔离开来
如果有一个函数只在某一个.cc 文件里面使用, 那么可以将这个函数放在unnamed namespace 或者用static 声明 static int foo() 这种