缩进
1、使用空格键(SPACE),不要使用表格键(TAB)。表格键应该只出现于表达对应语 义的文件里,例如,Makefile文件。
2、缩进大小为4个空格。
正确:
int main()
{
return 0;
}
错误:
int main()
{
return 0;
}
3、最外层namespace命名空间块的内容(包括最外层命名空间块的子命名空间块)不应该缩进。子命名空间块的内容应该缩进。
正确:
// Document.h
namespace WebCore {
class Document {
Document();
...
};
namespace NestedNamespace {
...
}
} // namespace WebCore
// Document.cpp
namespace WebCore {
Document::Document()
{
...
}
} // namespace WebCore
错误:
// Document.h
namespace WebCore {
class Document {
Document();
...
};
namespace NestedNamespace {
...
}
} // namespace WebCore
// Document.cpp
namespace WebCore {
Document::Document()
{
...
}
} // namespace WebCore
4、switch语句的case语句的标签不要缩进。而case语句的内容需要缩进。
正确:
switch (condition) {
case fooCondition:
case barCondition:
i++;
break;
default:
i--;
}
错误:
switch (condition) {
case fooCondition:
case barCondition:
i++;
break;
default:
i--;
}
5、布尔表达式中,如果同级的表达式位于不同的行,运算符应该位于左边,而不是右边。
正确:
if (attr->name() == srcAttr
|| attr->name() == lowsrcAttr
|| (attr->name() == usemapAttr && attr->value().domString()[0] != '#'))
return;
错误:
if (attr->name() == srcAttr ||
attr->name() == lowsrcAttr ||
(attr->name() == usemapAttr && attr->value().domString()[0] != '#'))
return;
空格
1、一元运算符左右不要有空格。
正确:
i++;
错误:
i ++;
2、二元运算符和三元运算符左右要有空格。
正确:
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;
3、逗号和分号前面不要有空格。
正确:
for (int i = 0; i < 10; ++i)
doSomething();
f(a, b);
错误:
for (int i = 0 ; i < 10 ; ++i)
doSomething();
f(a , b) ;
4、条件语句(例如,if)和其括号之间要有空格。
正确:
if (condition)
doIt();
错误:if(condition)
doIt();
5、函数与其括号之间,以及括号与其内容之间不要有空格。
正确:
f(a, b);
错误:
f (a, b);
f( a, b );
换行
1、一行一个语句。
正确:
x++;
y++;
if (condition)
doIt();
错误:
x++; y++;
if (condition) doIt();
2、如果前面是一个右花括号,else语句应该与右花括号位于同一行;如果不是,else语语应该另起一行,与if语句位于一列。
正确:
if (condition) {
...
} else {
...
}
if (condition)
doSomething();
else
doSomethingElse();
if (condition)
doSomething();
else {
...
}
错误:
if (condition) {
...
}
else {
...
}
if (condition) doSomething(); else doSomethingElse();
if (condition) doSomething(); else {
...
}
3、如果else if语句的前一个if语句以return语句结束,那么这个else if语句应该改写为一个if语句。
正确:
if (condition) {
...
return someValue;
}
if (condition) {
...
}
错误:
if (condition) {
...
return someValue;
} else if (condition) {
...
}
花括号
1、函数定义(函数体花括号):各自位于单独的一行中。
正确:
int main()
{
...
}
错误:
int main() {
...
}
2、其他花括号:打开花括号(左花括号)位于代码块的前一行中;关闭花括号(右花括号)位于单独的一行中。
正确:
class MyClass {
...
};
namespace WebCore {
...
}
for (int i = 0; i < 10; ++i) {
...
}
错误:
class MyClass
{
...
};
3、条件语句的代码块只有一行的情况,不应该有花括号。但是,如果有代码注释或者将该语句写成多行时,就应该有花括号。
正确:
if (condition)
doIt();
if (condition) {
// Some comment
doIt();
}
if (condition) {
myFunction(reallyLongParam1, reallyLongParam2, ...
reallyLongParam5);
}
错误:
if (condition) {
doIt();
}
if (condition)
// Some comment
doIt();
if (condition)
myFunction(reallyLongParam1, reallyLongParam2, ...
reallyLongParam5);
4、没有代码块的控制语句,应以一对花括号表示。
正确:
for ( ; current; current = current->next) { }
错误:
for ( ; current; current = current->next);
Null,false以及0
1、在C++中,null指针的值应为0。在C中,null指针的值应为NULL。在Object-C和Obejct-C++中,分别与C和C++的情况一样,另一方面,Object-C对象的空值应为nil。
2、C++和C的布尔值(bool)应该写成true和false。Object-C布尔值(BOOL)应该写成YES和NO。
3、判断true/false,null/non-null,以及0/非0不要通过等号运算符来完成。
正确:
if (condition)
doIt();
if (!ptr)
return;
if (!count)
return;
错误:
if (condition == true)
doIt();
if (ptr == NULL)
return;
if (count == 0)
return;
4、在Object-C中,实例变量会自动以0初始化。所以,不要在一个初始化方法中额外添加将变量初始化为nil或NO的逻辑。
浮点数字面量
1、除非需要强制转换才能使用浮点运算的情况,不要对浮点数字面量额外增加.0,.f以及.0f。
正确:
const double duration = 60;
void setDiameter(float diameter)
{
radius = diameter / 2;
}
setDiameter(10);
const int framesPerSecond = 12;
double frameDuration = 1.0 / framesPerSecond;
错误:
const double duration = 60.0;
void setDiameter(float diameter)
{
radius = diameter / 2.f;
}
setDiameter(10.f);
const int framesPerSecond = 12;
double frameDuration = 1 / framesPerSecond; // integer division
命名
1、使用“骆驼拼写法”(CamelCase)。对于类名,结构名,协议名,或者命名空间名,第一个字母使用大写,如果开头为缩略词,则缩略词全部使用大写。对于变量名,或者函数名,第一个字母使用小写,如果开头为缩略词,则缩略词全部使用小写。
正确:
struct Data;
size_t bufferSize;
class HTMLDocument;
String mimeType();
错误:
struct data;
size_t buffer_size;
class HtmlDocument;
String MIMEType();
2、使用完整的单词。在极少数情况,使用缩词反而更合适、更易读时,则使用缩略词。
正确:
size_t characterSize;
size_t length;
short tabIndex; // more canonical
错误:
size_t charSize;
size_t len;
short tabulationIndex; // bizarre
3、C++类中的数据成员应该为私有成员。静态的数据成员的命名应该以“s_”为前缀。其他数据成员应该以“m_”为前缀。
正确:
class String {
public:
...
private:
short m_length;
};
错误:
class String {
public:
...
short length;
};
4、Object-C实例变量的命名应该以“_”为前缀。
正确:
@class String
...
short _length;
@end
错误:
@class String
...
short length;
@end
5、布尔变量的命名应该以类似于以“is”和“did”为前缀。
正确:
bool isValid;
bool didSendData;
错误:
bool valid;
bool sentData;
6、setter函数应以“set”为前缀。getter函数不需要以“get”为前缀。setter函数和getter函数应该包含get/set变量的名字。
正确:
void setCount(size_t); // sets m_count
size_t count(); // returns m_count
错误:
void setCount(size_t); // sets m_theCount
size_t getCount();
7、对于通过out参数返回值的getter函数,应以“get”为前缀。
正确:
void getInlineBoxAndOffset(InlineBox*&, int& caretOffset) const;
错误:
void inlineBoxAndOffset(InlineBox*&, int& caretOffset) const;
8、函数的名称应以对应的动词短词命名。
正确:
bool convertToASCII(short*, size_t);
错误:
bool toASCII(short*, size_t);
9、对于无意义参数名,不需要写在函数声明中。一个好的准则是,如是参数的类型名包含了参数名(不包括尾部的数字或者复数形式),那么,参数名就不需要。一般来说,对于布尔、字符串,以及数值类型的参数,不应该省略。
正确:
void setCount(size_t);
void doSomething(ScriptExecutionContext*);
错误:
void setCount(size_t count);
void doSomething(ScriptExecutionContext* context);
10、对于函数参数为“布尔类型”的值时,可以考虑将布尔类型改为枚举类型。因为枚 举类型更易读。另外,setter函数是一个例外,因为函数名已经清楚地告知布尔值是什 么意思了。
正确:
doSomething(something, AllowFooBar);
paintTextWithShadows(context, ..., textStrokeWidth > 0, isHorizontal());
setResizable(false);
错误:
doSomething(something, false);
setResizable(NotResizable);
11、Object-C的方法名称应该符合Cocoa命名规则:方法名称应该是一个动词短词,以 及每一个选择器(selector)应该使用以小写字母开头的骆驼拼写法。
12、枚举成员的命名应该使用以大写字母开头的骆驼拼写法。
13、const比#define更好。内联函数比宏更好。
14、#define常量应该以下划线分隔的大写单词命名。
15、需要被扩展成函数调用或其他计算的宏,而不是简单表示常量的宏:这些宏的命名 应该要像一个函数,以及应该以一对括号结束,即使它们没有参数(除非一些特殊的宏, 例如,ASSERT)。注意,在这种情况下,建议不要使用宏,而是使用内联函数。
正确:
#define WBStopButtonTitle() \
NSLocalizedString(@"Stop", @"Stop button title")
错误:
#define WB_STOP_BUTTON_TITLE \
NSLocalizedString(@"Stop", @"Stop button title")
#define WBStopButtontitle \
NSLocalizedString(@"Stop", @"Stop button title")
16、#define,#ifdef“头文件”应该命名为与对应的头文件一样的名字(需要将“点号” 替换为“下划线”)。
正确:
// HTMLDocument.h
#ifndef HTMLDocument_h
#define HTMLDocument_h
错误:
// HTMLDocument.h
#ifndef _HTML_DOCUMENT_H_
#define _HTML_DOCUMENT_H_
其他标点符号
1、C++类的构造函数应该通过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() {}
2、对于Vector,使用下标比使用迭代器更好、更简洁以及易读。
正确:
size_t frameViewsCount = frameViews.size();
for (size_t i = i; i < frameViewsCount; ++i)
frameViews[i]->updateLayoutAndStyleIfNeededRecursive();
错误:
const Vector<RefPtr<FrameView> >::iterator end = frameViews.end();
for (Vector<RefPtr<FrameView> >::iterator it = frameViews.begin(); it != end; ++it)
(*it)->updateLayoutAndStyleIfNeededRecursive();
指针和引用
1、在非C++代码中的指针类型 - 指针类型应该写成类型和星号(*)之间以一个空格 分隔(所以,星号与接下来的变量名之间不要空格)。
2、在C++代码中的指针类型和引用类型 - 指针类型和引用类型应该写成类型和星号 和&号之间不要有空格。
正确:
Image* SVGStyledElement::doSomething(PaintInfo& paintInfo)
{
SVGStyledElement* element = static_cast<SVGStyledElement*>(node());
const KCDashArray& dashes = dashArray();
错误:
Image *SVGStyledElement::doSomething(PaintInfo &paintInfo)
{
SVGStyledElement *element = static_cast<SVGStyledElement *>(node());
const KCDashArray &dashes = dashArray();
3、一个函数的out参数,一般来说,应该使用引用类型。除非out参数是可选的情况下,则应该使用指针类型。
正确:
void MyClass::getSomeValue(OutArgumentType& outArgument) const
{
outArgument = m_value;
}
void MyClass::doSomething(OutArgumentType* outArgument) const
{
doSomething();
if (outArgument)
*outArgument = m_value;
}
错误:
void MyClass::getSomeValue(OutArgumentType* outArgument) const
{
*outArgument = m_value;
}
#include语句
1、所有的实现文件必须首先包含(#include)“config.h”文件。头文件绝不包含“config.h” 文件。
正确:
// RenderLayer.h
#include "Node.h"
#include "RenderObject.h"
#include "RenderView.h"
错误:
// RenderLayer.h
#include "config.h"
#include "RenderObject.h"
#include "RenderView.h"
#include "Node.h"
2、所有的实现文件必须在包含(#include)“config..h”后,包含主头文件。例如,Node.cpp应该在其他头文件(不包括config.h)之前首先包含Node.h。这就保证了每一个头文件的完整性。而且,也保证了每一个头文件,在不要求其他头文件的情况下,也可以成功编译。
3、其他#include语句应该以文件名排序的顺序出现(大小写敏感,可以通过命令行的排序工具或Xcode排序选择命令)。没有必要以逻辑顺序排序。
正确:
// HTMLDivElement.cpp
#include "config.h"
#include "HTMLDivElement.h"
#include "Attribute.h"
#include "HTMLElement.h"
#include "QualifiedName.h"
错误:
// HTMLDivElement.cpp
#include "HTMLElement.h"
#include "HTMLDivElement.h"
#include "QualifiedName.h"
#include "Attribute.h"
4、包含系统头文件必须们于其他头文件后面。
正确:
// ConnectionQt.cpp
#include "ArgumentEncoder.h"
#include "ProcessLauncher.h"
#include "WebPageProxyMessageKinds.h"
#include "WorkItem.h"
#include <QApplication>
#include <QLocalServer>
#include <QLocalSocket>
错误:
// ConnectionQt.cpp
#include "ArgumentEncoder.h"
#include "ProcessLauncher.h"
#include <QApplication>
#include <QLocalServer>
#include <QLocalSocket>
#include "WebPageProxyMessageKinds.h"
#include "WorkItem.h"
“using”语句
1、在头文件里,在某个命名空间(或全局命名空间)的范围里,不要使用“using”语句。
正确:
// wtf/Vector.h
namespace WTF {
class VectorBuffer {
using std::min;
...
};
} // namespace WTF
错误:
// wtf/Vector.h
namespace WTF {
using std::min;
class VectorBuffer {
...
};
} // namespace WTF
2、在WTF子库的头文件里,允许在文件的底部使用“usnig”语句来导入一个或多个位于WTF命名空间的名称到全局命名空间里。
正确:
// wtf/Vector.h
namespace WTF {
} // namespace WTF
using WTF::Vector;
错误:
// wtf/Vector.h
namespace WTF {
} // namespace WTF
using namespace WTF;
错误:
// runtime/UString.h
namespace WTF {
} // namespace WTF
using WTF::PlacementNewAdopt;
3、在C++实现文件里,不要使用“using std::foo”这样的语句来导入在STL里的名称。而应该使用“using namespace std”。
正确:
// HTMLBaseElement.cpp
using namespace std;
namespace WebCore {
} // namespace WebCore
错误:
// HTMLBaseElement.cpp
using std::swap;
namespace WebCore {
} // namespace WebCore
4、在实现文件里,如果一个“using namespace”语句是为导入一个子命名空间,而这个子命名空间的父命名空间是在本文件中定义的,那么,将这个语句移到这个父命名空间的定义里。
正确:
// HTMLBaseElement.cpp
namespace WebCore {
using namespace HTMLNames;
} // namespace WebCore
错误:
// HTMLBaseElement.cpp
using namespace WebCore::HTMLNames;
namespace WebCore {
} // namespace WebCore
5、在实现文件里,将其他“using”语句放在文件的开头,在命名空间的定义之前以及任何一个“include”语句的后面。
正确:
// HTMLSelectElement.cpp
using namespace std;
namespace WebCore {
} // namespace WebCore
错误:
// HTMLSelectElement.cpp
namespace WebCore {
using namespace std;
} // namespace WebCore
类
1、当被转换的参数能被理解为一个类型转换,以及类型转换是快速时,使用构造函数 来进行隐式类型转换。否则,使用explicit关键字,或者使用返回对应类型的函数。这 条规则应用于单参数的构造函数。
正确:
class LargeInt {
public:
LargeInt(int);
...
class Vector {
public:
explicit Vector(int size); // Not a type conversion.
PassOwnPtr<Vector> create(Array); // Costly conversion.
...
错误:
class Task {
public:
Task(ScriptExecutionContext*); // Not a type conversion.
explicit Task(); // No arguments.
explicit Task(ScriptExecutionContext*, Other); // More than one argument.
注释
1、在语句结尾处的注释,与语句的结尾处之间以一个空格隔开。另外,注释中的每一个句子也只以一个空格隔开。
正确:
f(a, b); // This explains why the function call was done. This is another sentence.
错误:
int i; // This is a comment with several spaces before it, which is a non-conforming style.
double f; // This is another comment. There are two spaces before this sentence which is a non-conforming style.
2、使注释像句子一样,以大写开头,并以句号结束。对于语句结尾后面的注释是一个例外,例如:"if (x == y) // false for NaN".
3、使用FIXME:(不需要指明解决人)来表示待解决的问题。
正确:
drawJpg(); // FIXME: Make this code handle jpg in addition to the png support.
错误:
drawJpg(); // FIXME(joe): Make this code handle jpg in addition to the png support.
drawJpg(); // TODO: Make this code handle jpg in addition to the png support.
原文地址:http://www.webkit.org/coding/coding-style.html