CodeStyle


CppStyle

Naming(命名)

命名方案

  • CamelCased :名称以大写字母开头,每个新单词都有一个大写字母,没有下划线
  • camelCased :类似CamelCase,但首字母小写
  • under_scored :名称仅使用小写字母,单词由下划线分隔(under_scored 应该是 underscored
  • ALL_CAPITALS : 所有大写字母,单词用下划线分隔

Packages(功能包)

  • under_scored

Topics / Services(话题/服务)

  • under_scored

Files(文件)

  • 所有文件都是 under_scored
  • 源文件的扩展名为 .cpp
  • 头文件的扩展名为 .h
  • 需带有描述性,例如,适用hokuyo_topurg_laser.cpp而不是laser.cpp
  • 如果该文件主要实现一个类,则以该类命名该文件。 例如,类 ActionServer将存在于文件 action_server.h

Libraries(库)

  • under_scored
  • 不要在库名的前缀lib后面插入下划线

例如:

lib_my_great_thing ## Bad
libmy_great_thing ## Good

Classes / Types(类/数据类型)

  • 类以及其他数据类型都是CamelCased,例如:
class ExampleClass;
  • 如果类名包含简短的首字母缩略词,则首字母缩略词本身应该全部大写,例如:
class HokuyoURGLaser;

Function / Methods(函数/方法)

  • 通常,函数和类方法都是camelCased,参数是under_scored
int exampleMethod(int example_arg);

通常,函数和方法执行一个操作,所以它们的名称应该清楚地表达它们的作用,例如,用checkForErrors() 代替 errorCheck(),用dumpDataToFile() 代替 dataFile()

Variables(变量)

  • 通常,变量是under_scored
  • 进行合理的描述,尽量不要含糊其辞
  • STL 迭代器变量应该表明它们正在迭代什么,例如:
std::list pid_list; 
std::list::iterator pid_it;
  • 或者,STL 迭代器可以指示它可以指向的元素类型,例如:
std::list pid_list; 
std::list::iterator int_it;

Member variables(成员变量)

  • 作为类成员的变量(有时称为字段)是 under_scored ,并添加了尾随下划线,例如:
int example_int_; 

Global variables(全局变量)

  • 全局变量是under_scored加上g_前缀

  • 几乎不应该使用全局变量

// I tried everything else, but I really need this global variable
int g_shutdown;

Namespaces (名称空间)

  • under_scored

Formatting(格式)

  • 每个缩进2个空格
  • 命名空间的内容不缩进
  • 大括号,无论是打开的还是关闭的,都有自己的线条(没有“拥抱的大括号”),例如:
if(a < b)
{
  // do stuff
}
else
{
  // do other stuff
}
  • 如果封闭的块是单行语句,则可以省略大括号,例如:
if(a < b)
  x = 2*a;
  • 如果封闭的块更复杂,请始终包含大括号,例如:
if(a < b)
{
  for(int i=0; i<10; i++)
    PrintItem(i);
}

例子

/*
 * A block comment looks like this...
 */
#include 
class Point
{
public:
  Point(double xc, double yc) :
    x_(xc), y_(yc)
  {
  }
  double distance(const Point& other) const;
  int compareX(const Point& other) const;
  double x_;
  double y_;
};
double Point::distance(const Point& other) const
{
  double dx = x_ - other.x_;
  double dy = y_ - other.y_;
  return sqrt(dx * dx + dy * dy);
}
int Point::compareX(const Point& other) const
{
  if (x_ < other.x_)
  {
    return -1;
  }
  else if (x_ > other.x_)
  {
    return 1;
  }
  else
  {
    return 0;
  }
}
namespace foo
{
int foo(int bar) const
{
  switch (bar)
  {
    case 0:
      ++bar;
      break;
    case 1:
      --bar;
    default:
    {
      bar += bar;
      break;
    }
  }
}
} // end namespace foo

#ifndef guards

  • 防止头文件被重复包含
#ifndef PACKAGE_PATH_FILE_H
#define PACKAGE_PATH_FILE_H
...
#endif

Output arguments (输出参数)

  • 方法/函数的输出参数(即函数可以修改的变量)通过指针传递,而不是通过引用传递,例如:
int exampleMethod(FooThing input, BarThing* output);

Namespaces(名称空间)

  • 鼓励使用命名空间来限定代码的范围。 根据包的名称选择一个描述性名称
  • 切勿使用在头文件中使用using 指令 。 这样做会污染包含标头的所有代码的命名空间
  • 例如:
using namespace std; // Bad, because it imports all names from std::
using std::list;  // I want to refer to std::list as list
using std::vector;  // I want to refer to std::vector as vector

Enumerations(枚举)

  • 使用作用域枚举
enum class Choise
{
    Choice1,
    Choice2,
    Choice3
};
Choise c = Choise::Choice1;
ROS