缩进
- 使用空格而不是Tab。Tab只应该出现在有语义的文件里,如makefile文件。
- 缩进大小为4个空格。
正确:int main() { return 0; }
错误:
int main() { return 0; }
- 在头文件中,命名空间中的代码应该被缩进。
正确:// Document.h namespace WebCore { class Document { Document(); ... }; } // namespace WebCore
错误:
// Document.h namespace WebCore { class Document { Document(); ... }; } // namespace WebCore
- 在实现文件中,命名空间中的代码不应该缩进。
正确:// Document.cpp namespace WebCore { Document::Document() { ... } } // namespace WebCore
错误:
// Document.cpp namespace WebCore { Document::Document() { ... } } // namespace WebCore
- case标签应该和switch对齐,case下的语句要缩进。
正确:switch (condition) { case fooCondition: case barCondition: i++; break; default: i--; }
错误:
switch (condition) { case fooCondition: case barCondition: i++; break; default: i--; }
- 当同一层面的布尔表达式跨多个行时,布尔操作符应该放在行首而不是后面。
正确:return attr->name() == srcAttr || attr->name() == lowsrcAttr || (attr->name() == usemapAttr && attr->value().domString()[0] != '#');
错误:
return attr->name() == srcAttr || attr->name() == lowsrcAttr || (attr->name() == usemapAttr && attr->value().domString()[0] != '#');
空格
- 一元操作符前不加空格。
正确:i++;
错误:
i ++;
- 二元与三元操作符前后应该加上空格。
正确:y = m * x + b; f(a, b); c = a | b; return condition ? 1 : 0;
错误:
y=m*x+b; f(a,b); c = a|b; return condition ? 1:0;
- 控制语句与圆括号之间要加空格。
正确:if (condition) doIt();
错误:
if(condition) doIt();
- 函数调用时,函数名和圆括号之间、圆括号与其内容之间不留空格。
正确:f(a, b);
错误:
f (a, b); f( a, b );
换行
- 每个语句占用一行。
正确:x++; y++; if (condition) doIt();
错误:
x++; y++; if (condition) doIt();
- else关键字应该和前面大括号在一行。
正确:if (condition) { ... } else { ... }
错误:
if (condition) { ... } else { ... }
- 当前一个if语句被return语句终止时,else if语句应该写成多个if语句的形式。
正确:if (condition) { ... return someValue; } if (condition) { ... }
错误:
if (condition) { ... return someValue; } else if (condition) { ... }
大括号
- 行数定义:每个大括号占用一行。
正确:int main() { ... }
错误:
int main() { ... }
- 其它大括号:左括号放在前一条语句之后,右括号单独占用一行。
正确:class MyClass { ... }; namespace WebCore { ... } for (int i = 0; i < 10; i++) { ... }
错误:
class MyClass { ... };
- 仅有一行的条件控制语句不使用大括号。
正确:if (condition) doIt();
错误:
if (condition) { doIt(); }
- 条件子句为空的情况下,大括号不能省略。
正确:for ( ; current; current = current->next) { }
错误:
for ( ; current; current = current->next);
Null,False和0
- C++语言中,空指针被写成0,而在C语言中,空指针被写成NULL。在Objective-C和Objective-C++中,使用nil表示一个空Objective-C对象。
- C和C++的bool值应该被写作true和false。Objective-C的BOOL值则用YES和NO表示。
- 检查真/假、空/非空以及零/非零不应该使用等式。
正确:if (condition) doIt(); if (!ptr) return; if (!count) return;
错误:
if (condition == true) doIt(); if (ptr == NULL) return; if (count == 0) return;
- 在Objective-C中,实例变量自动被初始化为0,不要再初始化函数中额外的初始化为nil或NO。
命名
- 采用骆驼命名法(CamelCase,依靠单词的大小写拼写复合词的做法)。class,struct,protocol,namespace名字的第一个字母大写;变量和函数名的第一个单词小写;缩写应完全大写。
正确:struct Data; size_t bufferSize; class HTMLDocument;
错误:
struct data; size_t buffer_size; class HtmlDocument;
- 使用完整的单词,除非特殊情况下缩写更规范和更容易理解。
正确:size_t characterSize; size_t length; short tabIndex; // more canonical
错误:
size_t charSize; size_t len; short tabulationIndex; // bizarre
- C++中类的数据成员采用“m_”前缀。
正确:class String { ... short m_length; };
错误:
class String { ... short length; };
- Objective-C实例变量采用“_”作为前缀。
正确:@class String ... short _length; @end
错误:
@class String ... short length; @end
- 布尔变量前加上is或者did之类的前缀。
正确:bool isValid; bool didSendData;
错误:
bool valid; bool sentData;
- setter方法前使用set开头,而在getter方法中采用“裸字”。setter和getter方法的命名应该和需要存储的变量相匹配。
正确:void setCount(size_t); // sets m_count size_t count(); // returns m_count
错误:
void setCount(size_t); // sets m_theCount size_t getCount();
- 在函数名字中采用说明性的动词。
正确:bool convertToASCII(short*, size_t);
错误:
bool toASCII(short*, size_t);
- 在函数的声明中丢弃无意义的参数变量名。
正确:void setCount(size_t);
错误:
void setCount(size_t count);
- Objective-C的方法命名应遵循Cocoa命名规则——读起来像短语,并且each piece of the selector should start with a lowercase letter and use intercaps(没看懂:()。
- Enum members should user InterCaps with an initial capital letter。(也没看懂,就是这个InterCaps不知道什么意思)。
- 常量优先使用#define,宏优先使用inline函数。
- #defined定义的常量的所有字母都大写,单词间用下划线分隔。
- 对于展开为函数调用或者其它非常量计算的宏:命名方法和函数一致,并且不管有没有参数都应该以一对圆括号结束(一些特殊的宏例外,如ASSERT)。注意在这种情况,采用inline函数代替宏也许是更好的办法。
正确:#define WBStopButtonTitle() / NSLocalizedString(@"Stop", @"Stop button title")
错误:
#define WB_STOP_BUTTON_TITLE / NSLocalizedString(@"Stop", @"Stop button title") #define WBStopButtontitle / NSLocalizedString(@"Stop", @"Stop button title")
- #ifndef,#define“头文件卫士”应该严格按照文件名来命名(大小写也要一致),将文件名中的“.”替换成“_”。
正确:// HTMLDocument.h #ifndef HTMLDocument_h #define HTMLDocument_h
错误:
// HTMLDocument.h #ifndef _HTML_DOCUMENT_H_ #define _HTML_DOCUMENT_H_
其它标点
- C++类的构造函数应该初始化所有成员变量。每个成员变量(以及父类)都要进行缩进,并且各占一行,每行都使用冒号和逗号开始。
正确:MyClass::MyClass(Document* doc) : MySuperClass() , m_myMember(0) , m_doc(doc) { } MyOtherClass::MyOtherClass() : MySuperClass() { }
错误:
MyClass::MyClass(Document* doc) : MySuperClass() { m_myMember = 0; m_doc = doc; } MyOtherClass::MyOtherClass() : MySuperClass() {}
- 非C++代码中的指针类型——类型和*之间必须有空格(*尽可能靠近后面的标志符)。
- C++代码中的指针和引用类型——类型和*或&之间没有空格。
正确:Image* SVGStyledElement::doSomething(PaintInfo& paintInfo) { SVGStyledElement* element = static_cast(node()); const KCDashArray& dashes = dashArray();
错误:
Image *SVGStyledElement::doSomething(PaintInfo &paintInfo) { SVGStyledElement *element = static_cast(node()); const KCDashArray &dashes = dashArray();
#include语句
- 所有文件必须首先#include “config.h”。
- 紧跟”config.h”之后应该包含主头文件,例如,Node.cpp应该在包含其它头文件前包含Node.h。这将保证每一个头文件的完整性会经过测试,不依赖于其它任何头文件就可以通过编译。
- 其它所有#include语句应该以一定顺序给出(区分大小写,可利用命令行工具或编辑器的排序功能),不要煞费苦心的以一定的逻辑排序。