学习Google C++ Style Guide笔记,规范自己的c++代码,没有翻译全部内容,只记录部分内容。
函数参数顺序
先输入,后输出;输入参数传值或是const引用,输出参数使用非const指针。
头文件顺序
1. dir2/foo.cc文件所对应的头文件dir2/foo.h
2. c系统文件
3. c++系统文件
4. 其他的库文件
5. 你的项目头文件
将对应头文件放在第一位的好处是在编译时可以快速发现源文件中的错误
例子:
源文件的路径 google-awesome-project/src/foo/internal/fooserver.cc,它的头文件顺序应该是
#include "foo/public/fooserver.h"
#include <sys/types.h>
#include <unistd.h>
#include <hash_map>
#include <vector>
#include "base/basictypes.h"
#include "base/commandlineflags.h"
#include "foo/public/bar.h"</span></span>
命名空间
1. 使用匿名的命名空间主要的作用是防止在全局范围内造成命名冲突
2. 不使用using关键字,保证不同命名空间的同名变量或参数可以使用
类构造函数
1. 构造函数中执行不重要的初始化动作,例如为某些参数初始化默认值2. 构造函数中不可以抛出异常,不能有返回值,需要抓异常或是判断返回值的操作不能放在构造函数中
3. 类实例化为全局变量,其构造函数会优先于main()函数执行,因此将类实例化为全局变量是危险的做法,在类的构造函数中访问到main()函数执行后的相关参数会导致未知的错误
4. 重要的初始化操作应该放在init()方法中
5. 提供默认构造函数用来初始化类属性,编译器提供的构造函数行为未知
类构造函数
在c++中class是struct的扩展,但是struct同样具有class的属性和功能,即函数重载和多态
不同点:
1. 成员变量的默认访问控制不同
struct是public而class是private
2. 默认继承方式不同
struct的默认继承方式public
class的默认继承方式private
所以struct应用与没有类方法的情况下
拷贝构造函数
类在拷贝赋值时会调用到拷贝构造函数,例如在函数通过值传递类类型参数时,以及返回类类型时
一般的类是不需要拷贝构造函数的,函数应该采用引用作为输入参数,而输出参数一般是类实例的指针
使用STL中的容器来存储自定义的数据结构时,需要定义拷贝构造函数,可以通过在STL中应该保存类实例的指针
隐藏拷贝构造函数的方法可以通过将拷贝构造函数声明为private,可以通过宏定义来简化声明
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName &); \
void operator=(const TypeName &)
class Foo {
public:
Foo();
~Foo();
private:
DISALLOW_COPY_AND_ASSIGN(Foo);
};
多重继承
1. 只允许基类中存在一个非抽象类,其他均为接口类,避免“菱形”问题
纯接口类
c++中的纯接口类相当于java中interface,具有以下几个特点
1. 只包含public的纯虚函数和静态函数(析构函数除外)
2. 不包含non-static成员变量
3. 构造函数不需要或是没有参数的protected构造函数
4. 只可以继承纯接口类
5. 可以再类的名字后加入Interface后缀
运算符重载
1. 尽量减少使用运算符重载,运算符重载增加了调试的困难
2. 可以通过重载equals()等方法代替重载运算符,这样看起来更直观
3. 在STL中必须重载运算符的时候,应该提供说明
拷贝构造函数
类在拷贝赋值时会调用到拷贝构造函数,例如在函数通过值传递类类型参数时,以及返回类类型时#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName &); \
void operator=(const TypeName &)
class Foo {
public:
Foo();
~Foo();
private:
DISALLOW_COPY_AND_ASSIGN(Foo);
};
多重继承
1. 只允许基类中存在一个非抽象类,其他均为接口类,避免“菱形”问题纯接口类
c++中的纯接口类相当于java中interface,具有以下几个特点运算符重载
类成员声明顺序
1. 大顺序是 public > protected > private
2. 每个区域内部的顺序 Typedefs and Enums > Constants (static const) > Constructor > Destructor > Methods > Data Members
引用参数
void Foo(const string &in, string *out);
void Foo(const string *in, string *out);
输入参数为传值或传const引用,输出参数为指针
输入参数在某些情况下可以使用const指针,需要特别说明,这些情况例如传递null指针或者函数要保存输入参数
函数重载
重载函数的前提是保证函数的功能是不变的,如果功能改变应该增加新的函数
减少使用默认参数,调用函数时应该清楚每一个参数的值
const关键字
在需要的地方尽可能的使用const关键字