9.4. 函数声明与定义

总述

返回类型和函数名在同一行, 参数也尽量放在同一行, 如果放不下就对形参分行, 分行方式与 函数调用 一致.

说明

函数看上去像这样:

  1. ReturnType ClassName::FunctionName(Type par_name1, Type par_name2) {
  2. DoSomething();
  3. ...
  4. }

如果同一行文本太多, 放不下所有参数:

  1. ReturnType ClassName::ReallyLongFunctionName(Type par_name1, Type par_name2,
  2. Type par_name3) {
  3. DoSomething();
  4. ...
  5. }

甚至连第一个参数都放不下:

  1. ReturnType LongClassName::ReallyReallyReallyLongFunctionName(
  2. Type par_name1, // 4 space indent
  3. Type par_name2,
  4. Type par_name3) {
  5. DoSomething(); // 2 space indent
  6. ...
  7. }

注意以下几点:

  • 使用好的参数名.
  • 只有在参数未被使用或者其用途非常明显时, 才能省略参数名.
  • 如果返回类型和函数名在一行放不下, 分行.
  • 如果返回类型与函数声明或定义分行了, 不要缩进.
  • 左圆括号总是和函数名在同一行.
  • 函数名和左圆括号间永远没有空格.
  • 圆括号与参数间没有空格.
  • 左大括号总在最后一个参数同一行的末尾处, 不另起新行.
  • 右大括号总是单独位于函数最后一行, 或者与左大括号同一行.
  • 右圆括号和左大括号间总是有一个空格.
  • 所有形参应尽可能对齐.
  • 缺省缩进为 2 个空格.
  • 换行后的参数保持 4 个空格的缩进.
    未被使用的参数, 或者根据上下文很容易看出其用途的参数, 可以省略参数名:
  1. class Foo {
  2. public:
  3. Foo(Foo&&);
  4. Foo(const Foo&);
  5. Foo& operator=(Foo&&);
  6. Foo& operator=(const Foo&);
  7. };

未被使用的参数如果其用途不明显的话, 在函数定义处将参数名注释起来:

  1. class Shape {
  2. public:
  3. virtual void Rotate(double radians) = 0;
  4. };
  5.  
  6. class Circle : public Shape {
  7. public:
  8. void Rotate(double radians) override;
  9. };
  10.  
  11. void Circle::Rotate(double /*radians*/) {}
  1. // 差 - 如果将来有人要实现, 很难猜出变量的作用.
  2. void Circle::Rotate(double) {}

属性, 和展开为属性的宏, 写在函数声明或定义的最前面, 即返回类型之前:

  1. MUST_USE_RESULT bool IsOK();