C/C++ 语法#
学习 C/C++ 是一个持久的战役,这个语言几乎每年都会有新的特性加进来,因此,我们不可能在博客中把所有的细节都表现出来。在学习的过程中,需要注重日积月累,把碰到的不会的东西逐渐地加以总结和凝练,用通俗易懂的方式重新表述一遍,是这个系列博客存在的意义。
另外,推荐一个可以在线运行 C/C++ 代码的环境:https://coliru.stacked-crooked.com
Google Code Style#
尽量不使用宏
不使用异常
禁止使用 RTTI
使用
printf
之类的代替流除位域不使用无符号数字
除特定环境,不使用操作符重载
使用 4 中
cast
运算符转换类型禁止使用
Class
类型全局变量,若使用必须为单例模式sizeof(var)
代替sizeof(type)
scoped_ptr
可以胜任智能指针特殊情况下可用
shared_ptr
任何时候都不使用
auto_ptr
// style.h (文件名全小写,可包含下划线或短线)
// Copyright 2008 Google Inc.
// License(BSD/GPL/...)
// Author: Your Name
// This file mainly describes ...
// 防止重复包含,宏格式为:<project>_<path>_<file>_
#ifndef PROJECT_EVENTLOOP_H_
#define PROJECT_EVENTLOOP_H_
// 头文件中尽量使用前置声明
// STL 类例外,不使用前置声明,使用 #include
class Channel;
// 命名空间全小写,顶头无空格,cpp 文件里提倡使用不具名命名空间
namespace mynamespace {
// 类名大写开头单词,使用组合通常比使用继承更适宜
// 若用继承,只用公有继承
// 另:接口类命名以 Interface 结尾
class EventLoop : public CallbackInterface {
public:
// 每一个限定符内,声明的顺序如下:
// 1 typedefs 和 enums
// 2 常量
// 3 构造函数
// 4 析构函数
// 5 成员函数,含静态数据成员
// 6 成员变量,含静态成员变量
typedef vector< int > IntVector;
// 枚举名同类名,大写开头单词
enum UrlTableErrors {
ERROR_OUT_OF_MEMORY = 0, /* 枚举成员:全大写下划线 */
ERROR_MALFORMED_INPUT,
};
// explicit 修饰但参数构造函数,防止隐式类型转换误用
explicit EventLoop(const int xx);
// 若定义了成员变量无其他构造函数,要定义一个默认构造函数
// EventLoop() {
// }
// 普通函数命名,大写开头单词
// 输入参数在前为 const 引用,输出参数在后为指针
// 不为参数设置缺省值
void Add(const std::string &input, Channel *output);
// 存取函数命名
// 取:同变量名
// 存:值函数名为 set_varname
// 短小的存取函数可用内联
int num_entries() const { /* 尽可能使用 const */
return num_entries_;
}
void set_num_entries(int num_entries) {
num_entries_ = num_entries;
}
// 仅在需要拷贝对象时,使用拷贝构造函数
private:
DISALLOW_COPY_AND_ASSIGN(EventLoop); // 不需要拷贝时,在 private 里使用 DISALLOW_COPY_ASSIGN 宏
// 变量用描述性名称,不要节约空间,让别人理解你的代码更重要
const int kDaysInWeek = 7; // const 变量用 k 开头,后跟大写开头单词
int num_entries_; // 变量命名:全小写,有意义的单词和下划线
int num_complated_connections_; // 类成员变量下划线结尾
Channel *channel_; // 头文件中只用了指针/引用,则前向声明而非引入头文件
};
} // namespace mynamespace
#endif // PORJECT_EVENTLOOP_H_ /* 保护宏结尾加注释 */
// style.cpp (文件名全小写,可包含下划线或短线)
// Copyright 2008 Google Inc.
// License(BSD/GPL/...)
// Author: Your Name
// This file mainly describes ...
// 包含次序标准化,避免隐藏依赖:
// 1 本类的声明(第一个包含本类 h 文件,有效减少依赖)
// 2 C 系统文件
// 3 C++ 系统文件
// 4 其他库头文件
// 5 本项目内头文件(避免使用 UNIX 文件路径和 . 和 ..)
#include "base/basictypes.h"
#include "eventloop.h"
#include "foo/public/bar.h"
#include <sys/types.h>
#include <vector>
// 可以在整个 cpp 文件和 h 文件的方法内使用 using
// 禁止使用 using namespace xxx 污染命名空间
using std::string;
namespace mynamespace {
EventLoop::EventLoop() : num_entries_(10), num_complated_connections_(false) {
}
ReturnType ClassName::ReallyLongFunctionName(const Type &par_name1, Type *par_name2) {
bool retval = DoSometing(averyveryveryverylongargument1, argument2, argument3);
if (condition) {
for (int i = 0; i < kSomeNumber; ++i) { /* 前置自增运算 */
if (this_one_thing > this_other_thing && a_third_thing == a_forth_thing) {
// 临时方案使用 TODO 注释,后面括号里加上你的大名,邮件地址
// TODO (zh6tao@gmail.com): zh6tao
}
}
} else {
nt j = g();
}
switch (var) {
case 0:
break;
default:
assert(false); /* 若 default 永不执行可使用 assert */
}
return x;
}
} // namespace mynamespace /* 命名空间结束注释 */
Clang Format#
首先在 VS Code 中安装 Clang Format 扩展,然后在项目根目录下创建 .clang-format
,文件内容如下:
# This configuration file can be used to auto-format the code base.
# Not all guidelines specified in CODING_STYLE are followed, so the
# result MUST NOT be committed indiscriminately, but each automated
# change should be reviewed and only the appropriate ones committed.
#
# The easiest way to apply the formatting to your changes ONLY,
# is to use the git-clang-format script (usually installed with clang-format).
#
# - Fix up formatting before committing
# 1. Edit and stage your files.
# 2. Run `git clang-format`.
# 3. Verify + correct + (un)stage changes.
# 4. Commit.
#
# - Fix up formatting after committing
# 1. Commit your changes.
# 2. Run `git clang-format HEAD~` - Refer the commit *before* your changes here.
# 3. Verify + correct changes, `git difftool -d` can help here.
# 4. Stage + commit, potentially with `--amend` (means to fixup the last commit).
#
# To run clang-format on all sourcefiles, use the following line:
# $ git ls-files 'src/*.[ch]' 'src/*.cc' | xargs clang-format -i -style=file
#
# You can find more information on the different config parameters in this file here:
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
---
AccessModifierOffset: -4
AlignAfterOpenBracket: AlwaysBreak
AlignEscapedNewlines: Left
AlignOperands: false
AllowShortFunctionsOnASingleLine: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterEnum: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: false
BreakInheritanceList: BeforeComma
BreakStringLiterals: false
ColumnLimit: 109
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 16
Cpp11BracedListStyle: false
ForEachMacros:
- BITMAP_FOREACH
- CMSG_FOREACH
- _DNS_ANSWER_FOREACH
- DNS_ANSWER_FOREACH
- _DNS_ANSWER_FOREACH_FLAGS
- DNS_ANSWER_FOREACH_FLAGS
- _DNS_ANSWER_FOREACH_FULL
- DNS_ANSWER_FOREACH_FULL
- _DNS_ANSWER_FOREACH_IFINDEX
- DNS_ANSWER_FOREACH_IFINDEX
- _DNS_QUESTION_FOREACH
- DNS_QUESTION_FOREACH
- FDSET_FOREACH
- FOREACH_BTRFS_IOCTL_SEARCH_HEADER
- FOREACH_DEVICE
- FOREACH_DEVICE_AND_SUBSYSTEM
- FOREACH_DEVICE_DEVLINK
- FOREACH_DEVICE_PROPERTY
- FOREACH_DEVICE_SYSATTR
- FOREACH_DEVICE_TAG
- FOREACH_DIRENT
- FOREACH_DIRENT_ALL
- FOREACH_INOTIFY_EVENT
- FOREACH_STRING
- FOREACH_SUBSYSTEM
- HASHMAP_FOREACH
- HASHMAP_FOREACH_IDX
- HASHMAP_FOREACH_KEY
- JOURNAL_FOREACH_DATA_RETVAL
- JSON_VARIANT_ARRAY_FOREACH
- JSON_VARIANT_OBJECT_FOREACH
- LIST_FOREACH
- LIST_FOREACH_AFTER
- LIST_FOREACH_BEFORE
- LIST_FOREACH_OTHERS
- LIST_FOREACH_SAFE
- MESSAGE_FOREACH_PART
- NULSTR_FOREACH
- NULSTR_FOREACH_PAIR
- OBJECT_PATH_FOREACH_PREFIX
- ORDERED_HASHMAP_FOREACH
- ORDERED_HASHMAP_FOREACH_KEY
- ORDERED_SET_FOREACH
- PATH_FOREACH_PREFIX
- PATH_FOREACH_PREFIX_MORE
- SD_HWDB_FOREACH_PROPERTY
- SD_JOURNAL_FOREACH
- SD_JOURNAL_FOREACH_BACKWARDS
- SD_JOURNAL_FOREACH_DATA
- SD_JOURNAL_FOREACH_FIELD
- SD_JOURNAL_FOREACH_UNIQUE
- SECCOMP_FOREACH_LOCAL_ARCH
- SET_FOREACH
- SET_FOREACH_MOVE
- STRV_FOREACH
- STRV_FOREACH_BACKWARDS
- STRV_FOREACH_PAIR
IndentPPDirectives: AfterHash
IndentWidth: 4
IndentWrappedFunctionNames: true
MaxEmptyLinesToKeep: 2
PenaltyBreakAssignment: 65
PenaltyBreakBeforeFirstCallParameter: 16
PenaltyBreakComment: 320
PenaltyBreakFirstLessLess: 50
PenaltyBreakString: 0
PenaltyExcessCharacter: 10
PenaltyReturnTypeOnItsOwnLine: 100
PointerAlignment: Right
SpaceAfterCStyleCast: true
SpaceAroundPointerQualifiers: Both
SpaceBeforeParens: ControlStatementsExceptForEachMacros
SpacesInAngles: true
TabWidth: 4
UseCRLF: false