这篇文章将介绍C++的Google编码规范。

Header Files

Self-contained Headers

The #define Guard

1
2
3
4
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif // FOO_BAR_BAZ_H_

Forward Declarations

Pros

  • save compile time.

    Cons

  • Forward declarations can hide a dependency, allowing user code to skip necessary recompilation when headers change.
  • A forward declaration may be broken by subsequent changes to the library. Forward declarations of functions and templates can prevent the header owners from making otherwise-compatible changes to their APIs, such as widening a parameter type, adding a template parameter with a default value, or migrating to a new namespace.
  • Forward declaring symbols from namespace std:: yields undefined behavior.
  • It can be difficult to determine whether a forward declaration or a full #include is needed. Replacing an #include with a forward declaration can silently change the meaning of code
    1
    2
    3
    4
    5
    6
    7
    8
    // b.h:
    struct B {};
    struct D : B {};
    // good_user.cc:
    #include "b.h"
    void f(B*);
    void f(void*);
    void test(D* x) { f(x); } // calls f(B*)

    If the #include was replaced with forward decls for B and D, test() would call f(void*).

  • Forward declaring multiple symbols from a header can be more verbose than simply #includeing the header.
  • Structuring code to enable forward declarations (e.g. using pointer members instead of object members) can make the code slower and more complex.

Inline Functions

=======
layout: landscape
title: 编码规范
date: 2016-10-16 11:10:03
categories: Cplusplus
tags: [Cplusplus,google,编码规范]

https://google.github.io/styleguide/cppguide.html

Header Files

Self-contained Headers

The #define Guard

1
2
3
4
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif // FOO_BAR_BAZ_H_

Forward Declarations

Pros

  • save compile time.

Cons

  • Forward declarations can hide a dependency, allowing user code to skip necessary recompilation when headers change.
  • A forward declaration may be broken by subsequent changes to the library. Forward declarations of functions and templates can prevent the header owners from making otherwise-compatible changes to their APIs, such as widening a parameter type, adding a template parameter with a default value, or migrating to a new namespace.
  • Forward declaring symbols from namespace std:: yields undefined behavior.
  • It can be difficult to determine whether a forward declaration or a full #include is needed. Replacing an #include with a forward declaration can silently change the meaning of code
1
2
3
4
5
6
7
8
// b.h:
struct B {};
struct D : B {};
// good_user.cc:
#include "b.h"
void f(B*);
void f(void*);
void test(D* x) { f(x); } // calls f(B*)

If the #include was replaced with forward decls for B and D, test() would call f(void)*.

  • Forward declaring multiple symbols from a header can be more verbose than simply #includeing the header.
  • Structuring code to enable forward declarations (e.g. using pointer members instead of object members) can make the code slower and more complex.

Inline Functions

Define functions inline only when they are small, say, 10 lines or fewer.

Another useful rule of thumb:it’s typically not cost effective to inline functions with loops or switch statements (unless, in the common case, the loop or switch statement is never executed)

Names and Order of Includes

  1. dir2/foo2.h.
  2. C system files.
  3. C++ system files.
  4. Other libraries’ .h files.
  5. Your project’s .h files.
1
2
3
4
5
6
7
8
9
10
11
#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"
1
2
3
4
5
6
7
#include "foo/public/fooserver.h"

#include "base/port.h" // For LANG_CXX11.

#ifdef LANG_CXX11
#include <initializer_list>
#endif // LANG_CXX11

Scoping

Namespaces

Unnamed Namespaces

  • Unnamed namespaces are allowed and even encouraged in .cc files, to avoid link time naming conflicts.
  • Do not use unnamed namespaces in .h files.

Named Namespaces

  • Do not declare anything in namespace std, including forward declarations of standard library classes.
  • You may not use a using-directive to make all names from a namespace available.
  • Do not use Namespace aliases at namespace scope in header files except in explicitly marked internal-only namespaces, because anything imported into a namespace in a header file becomes part of the public API exported by that file.
  • Do not use inline namespaces.