Google C++ Convention

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#The__define_Guard

 

Gist:

 

  1. 头文件:
  • #define: <PROJECT>_<PATH>_<FILE>_H_.
  • #include: 当forward declaration(for example: class A;) 够用时别再用#include了
    • 在没有类定义的情况下(For example, only declare class Foo), 依然可用的有:
      • 数据成员是Foo* or Foo&
      • 函数的参数是Foo
      • static数据成员是Foo
  • inline:
    • 不要inline 超过10行代码的函数
    • 尽量不要inline析构函数,因为析构函数会对父类的析构函数有潜在的调用
    • 不要inline有循环或者switch的函数
    • vitural, recursive函数一般不会被编译器认可为inline.
  • inline file
    • file name with -inl.h suffix
    • inline函数要定义在头文件里,简单的直接放在.h里,复杂的放在-inl.h里
    • -inl.h 同样放置模板函数的定义
  • 函数参数顺序
    • input -> output
    • input: const reference. output/input: non-const pointers
  • include头文件的顺序
    • preferred files(with our main purpose), C library, C++ library, other libraries' .h, your project's .h
    • 在上面满足的情况下,按字母排
  1. Scoping
  • Namespace
    • 匿名的namespace是鼓励的。 但是小心不注意违反了C++ ODR原则。
    • 在.h里别用匿名的namespace
    • named namespace wrap在 include, 全局的定义和申明, 其他namespace 的forward的class声明之后
    • 不能用using-directive把整个namespace包含进来, 但包含specific的方法,class是允许的,namespace alias也是允许的(但是要避免在公共的头文件里用)。
  • Nested Class
    • nested class 只能在包含它的类里forward-declared, 其他要使用nested class只能inlcude整个头文件定义
    • 尽量不要把nest class public, 除非是接口的一部分
  • 全局函数,static member, nonmember函数
    • 尽量不要定义全局函数,而是放到匿名namespace或者static-linkage里来限制范围
  • 本地变量
    • 在声明的时候初始化
    • 为了节省消耗,在loop外定义变量
    • 声明离使用越近越好
  • 静态以及全局变量
    • 由于静态,全局变量初始化的不确定性,不允许静态或者全局变量是非POD类型
    • 即使是POD对象,初始化不能依赖于可能发生初始化不确定性的函数
    • 实在需要非POD的话,可以申明为指针,并且在初始化确定的函数中初始化(main or pthread_once)
  1. Classes
  • 构造函数
    • 构造函数应该只放置成员变量的初始化,复杂的其他操作放到额外的init方法里。
    • 禁止在构造函数使用exception特性
    • 禁止在构造函数里使用virtual 函数,因为这里virtual函数不会dispatch
    • 构造函数里不要访问潜在的全局变量
    • always至少创建无参数的构造函数,不要交给compiler来做
    • 为了防止implict conversion, 在只有一个参数的构造函数前加explict, 如果有例外要用comments说明
  • 拷贝构造函数
    • 可以避免使用拷贝构造函数,比如改用pointer, reference在stl container中或者函数参数中
    • 不需要copyable的时候,把拷贝构造函数和赋值函数都要显式禁止了
    • 如果需要copyable, 尽量另外定义拷贝函数而不是使用拷贝构造函数,eg CopyFrom
  • Struct vs. Class
    • 只有当纯数据集合的时候才用struct, 并且struct里的函数只能和数据提取/设置有关, 其他的用class
  • 继承
    • 分为实现继承和接口继承
    • 继承要public inheritance
    • 对于实现继承,组合会是更好的选择
    • 对于子类的析构函数要为virtual, 如果class有virtual的函数
    • 禁止protected member function/variable
    • 重新实现virtual 函数,必须在前面同样加上virtual
  • 多重继承
    • 多重继承只能用在一个是真正父类, 其他都是接口;或者全是接口类的情况下
  • 接口类
    • suffix with Interface
    • 只有纯虚函数或者static成员函数
    • 没有非static成员变量
    • 只能有protected的无参数构造函数
  • 访问控制
    • 除了static const成员变量外,其他的都为private,并且提供set/get函数去访问
    • 命名规则:var: a_; getter: a(); setter: set_a()
    • setter/getter一般inline在.h里
  • 类成员声明顺序
    • public -> protected -> private
      • Typedefs and Enums
      • Constants (static const data members)
      • Constructors
      • Destructor
      • Methods, including static methods
      • Data Members (except static const data members)
    • 操作符重载
      • 尽量不要重载操作符, 如果实在要做,comment他
      • 不要重载&, 因为如果重载了会导致forward declare可能不安全
  1. Others
  • 参数
    • input: value/const reference/const pointer
    • ouput: pointer
    • 不允许non-const reference
  • 重载函数
    • 尽量用make sense 的函数名来代替重载函数, 让读者不看参数也能知道调用的是什么函数
  • 函数参数默认值
    • 为了防止copy-paste的时候发现旧的code在新的code里不适合,但是因为有默认值看不出来的情况,不要使用函数参数默认值,除非为了模仿可变长参数
  • 友元
    • 可以使用友元,在设计unittest的时候可以把unittest class作为 tested class的友元类
  • 异常
  • RTTI
    • 不使用RTTI, 可能就改用double-dispatch solution, 像 visitor design
  • Casting
    • 不要使用c-style casting, 像int x = (int)y;
    • 用const_cast 去掉const
    • 用static_cast代替c-sytle cast来转换值类型, 或者显式的把pionter转对
    • 除了在unit code里,其他地方不要使用dynamic_cast
    • 用reinterpret_cast去进行指针之间或者指针和int之间的不安全的转换
  • Stream
    • 别使用stream, 用printf + read/write代替
  • Preincrement and Predecrement
      • 用Preincrement and Predecrement代替post-, 如果效果一样的情况下
    •  Const
      • 尽量使用const, 在成员函数,变量中
      • 任何不变的地方都用const
    • Int
      • 注意int和uint
      • 用stdint里的int32_t等来明确指定长度,当需要的时候
    • 64位兼容性
      • 当要算指针的时候,用intptr_t代替
      • sizeof(void*) != sizeof(int)
      • 注意strcuture alignment
    • Macro
      • 尽量不用##生成名称
      • 不要再.h里定义macro
    • 0和NULL
      • 对应int用0, 指针用NULL,char用‘/0'
    • sizeof
      • 用sizeof(varname)代替sizeof(type), 因为var很可能会换type, 如果用type就太死板了

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值