首页Google C++ 编程规范pdf 整理版
Displaying Hidden Details in this Guide
This style guide contains many details that are initially hidden from view. They are marked by
the triangle icon, which you see here on your left. Click it now. You should see "Hooray" appear
Hooray! Now you know you can expand points to get more details. Alternatively, there's an
"expand all" at the top of this document.
C++ is the main development language used by many of Google's open-source projects. As
every C++ programmer knows, the language has many powerful features, but this power
brings with it complexity, which in turn can make code more bug-prone and harder to read and
The goal of this guide is to manage this complexity by describing in detail the dos and don'ts of
writing C++ code. These rules exist to keep the code base manageable while still allowing
coders to use C++ language features productively.
Style, also known as readability, is what we call the conventions that govern our C++ code.
The term Style is a bit of a misnomer, since these conventions cover far more than just source
One way in which we keep the code base manageable is by enforcing consistency. It is very
important that any programmer be able to look at another's code and quickly understand it.
Maintaining a uniform style and following conventions means that we can more easily use
"pattern-matching" to infer what various symbols are and what invariants are true about them.
Creating common, required idioms and patterns makes code much easier to understand. In
some cases there might be good arguments for changing certain style rules, but we
nonetheless keep things as they are in order to preserve consistency.
Another issue this guide addresses is that of C++ feature bloat. C++ is a huge language with
many advanced features. In some cases we constrain, or even ban, use of certain features.
We do this to keep code simple and to avoid the various common errors and problems that
these features can cause. This guide lists these features and explains why their use is
Open-source projects developed by Google conform to the requirements in this guide.
Note that this guide is not a C++ tutorial: we assume that the reader is familiar with the
In general, every .cc file should have an associated .h file. There are some common
exceptions, such as unittests and small .cc files containing just a main() function.
Correct use of header files can make a huge difference to the readability, size and
performance of your code.
The following rules will guide you through the various pitfalls of using header files.
The #define Guard
All header files should have #define guards to prevent multiple inclusion. The format of the
symbol name should be
Header File Dependencies
Don't use an #include when a forward declaration would suffice.
When you include a header file you introduce a dependency that will cause your code to be
recompiled whenever the header file changes. If your header file includes other header files,
any change to those files will cause any code that includes your header to be recompiled.
Therefore, we prefer to minimize includes, particularly includes of header files in other header
You can significantly minimize the number of header files you need to include in your own
header files by using forward declarations. For example, if your header file uses
the File class in ways that do not require access to the declaration of the File class, your
header file can just forward declare class File; instead of having to #include
How can we use a class Foo in a header file without access to its definition?
We can declare data members of type Foo* or Foo&.
We can declare (but not define) functions with arguments, and/or return values, of
type Foo. (One exception is if an argument Foo or const Foo& has a non-explicit,
one-argument constructor, in which case we need the full definition to support
automatic type conversion.)
We can declare static data members of type Foo. This is because static data
members are defined outside the class definition.
On the other hand, you must include the header file for Foo if your class subclasses Foo or
has a data member of type Foo.
Sometimes it makes sense to have pointer (or better, scoped_ptr) members instead of
object members. However, this complicates code readability and imposes a performance
penalty, so avoid doing this transformation if the only purpose is to minimize includes in header
Of course, .cc files typically do require the definitions of the classes they use, and usually
have to include several header files.
Note: If you use a symbol Foo in your source file, you should bring in a definition
for Foo yourself, either via an #include or via a forward declaration. Do not depend on the
symbol being brought in transitively via headers not directly included. One exception is
if Foo is used in myfile.cc, it's ok to #include (or forward-declare) Foo inmyfile.h, instead
Define functions inline only when they are small, say, 10 lines or less.
Definition:You can declare functions in a way that allows the compiler to expand them inline
rather than calling them through the usual function call mechanism.
Pros:Inlining a function can generate more efficient object code, as long as the inlined function
is small. Feel free to inline accessors and mutators, and other short, performance-critical
Cons:Overuse of inlining can actually make programs slower. Depending on a function's size,
inlining it can cause the code size to increase or decrease. Inlining a very small accessor
function will usually decrease code size while inlining a very large function can dramatically
increase code size. On modern processors smaller code usually runs faster due to better use
of the instruction cache.
A decent rule of thumb is to not inline a function if it is more than 10 lines long. Beware of
destructors, which are often longer than they appear because of implicit member- and
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
It is important to know that functions are not always inlined even if they are declared as such;
for example, virtual and recursive functions are not normally inlined. Usually recursive
functions should not be inline. The main reason for making a virtual function inline is to place
its definition in the class, either for convenience or to document its behavior, e.g., for
accessors and mutators.
The -inl.h Files
You may use file names with a -inl.h suffix to define complex inline functions when needed.
The definition of an inline function needs to be in a header file, so that the compiler has the
definition available for inlining at the call sites. However, implementation code properly
belongs in .cc files, and we do not like to have much actual code in .h files unless there is a
readability or performance advantage.
If an inline function definition is short, with very little, if any, logic in it, you should put the code
in your .h file. For example, accessors and mutators should certainly be inside a class
definition. More complex inline functions may also be put in a .h file for the convenience of the
implementer and callers, though if this makes the .h file too unwieldy you can instead put that
code in a separate -inl.h file. This separates the implementation from the class definition,
while still allowing the implementation to be included where necessary.
Another use of -inl.h files is for definitions of function templates. This can be used to keep
your template definitions easy to read.
Do not forget that a -inl.h file requires a #define guard just like any other header file.
Function Parameter Ordering
When defining a function, parameter order is: inputs, then outputs.
Parameters to C/C++ functions are either input to the function, output from the function, or
both. Input parameters are usually values or const references, while output and input/output
parameters will be non-const pointers. When ordering function parameters, put all input-only
parameters before any output parameters. In particular, do not add new parameters to the end
of the function just because they are new; place new input-only parameters before the output
This is not a hard-and-fast rule. Parameters that are both input and output (often
classes/structs) muddy the waters, and, as always, consistency with related functions may
require you to bend the rule.
Names and Order of Includes
Use standard order for readability and to avoid hidden dependencies: C library, C++ library,
other libraries' .h, your project's .h.
All of a project's header files should be listed as descentants of the project's source directory
without use of UNIX directory shortcuts . (the current directory) or .. (the parent directory).
For example, google-awesome-project/src/base/logging.h should be included as
.cc, whose main purpose is to implement or test the stuff in
your includes as follows:
1. dir2/foo2.h (preferred location — see details below).
2. C system files.
3. C++ system files.
4. Other libraries' .h files.
5. Your project's .h files.
The preferred ordering reduces hidden dependencies. We want every header file to be
compilable on its own. The easiest way to achieve this is to make sure that every one of them
is the first .h file #included in some .cc.
.h are often in the same directory
(e.g. base/basictypes_test.cc and base/basictypes.h), but can be in different
Within each section it is nice to order the includes alphabetically.
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额