“编码风格应该尽可能地合理、简洁”
√ 要求类的书写风格如下:
//单继承,写成一行
classs ClassName : public BaseClassName
//多重继承,写成多行
classs ClassName :
public BaseClassName1,
public BaseClassName2
{
public:
////////////////////////////////////////////////////////////////////////////////
//ctor & dtor
ClassName();
virtual ~ ClassName();
public:
////////////////////////////////////////////////////////////////////////////////
//public overrides,from BaseClassName1
virtual void Func1_1();
////////////////////////////////////////////////////////////////////////////////
//public overrides,from BaseClassName2
virtual void Func2_1();
////////////////////////////////////////////////////////////////////////////////
//public virtual method
virtual void Func3_1();
////////////////////////////////////////////////////////////////////////////////
//public methods
void Func1();
protected:
////////////////////////////////////////////////////////////////////////////////
// protected overrides,from BaseClassName1
virtual void Func1_1();
////////////////////////////////////////////////////////////////////////////////
// protected overrides,from BaseClassName2
virtual void Func2_1();
////////////////////////////////////////////////////////////////////////////////
// protected virtual method
virtual void Func3_1();
////////////////////////////////////////////////////////////////////////////////
// protected methods
void Func1();
private:
////////////////////////////////////////////////////////////////////////////////
// private methods
void Func1();
////////////////////////////////////////////////////////////////////////////////
// private Fields
type m_field1;
type m_field2;
}
√ 要求将花括号单独写在一行。
//不好
if(DoSomething()){
…
}
//不好
if(DoSomething()){…}
//好
if(DoSomething())
{
…
}
√ 要求if、for、do、while、case、switch、default等语句自占一行,且if、for、do、while
等语句的执行语句部分无论多少都要加括号
{}
√ 要求程序块要采用缩进风格编写,缩进的空格数为4个。
√ 要求相对独立的程序块之间、变量说明之后必须加空行。
×
不要把多个短语句写在一行中,即一行只写一条语句。
√ 要求较长的语句(>80字符)要分成多行书写。
√ 要求循环、判断等语句中若有较长的表达式或语句,则要进行适应的划分,长表达式要在低优先级操作符处划分新行,操作符放在新行之首。
例如,
if ((taskNo < MAXTASKNUMBER)
&& (taskNo>0))
{
…
}
例如,
//不好
rect.Length = 0; rect.Width = 0;
//好
rect. Length = 0;
rect. Width = 0;
√
要求
注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级。
例如,
//不好
high << 8 | low
a | b && a & c
a | b < c & d
//好
word = (high << 8) | low
if ((a | b) && (a & c))
if ((a | b) < (c & d))
√ 要求在形式参数之间的逗号后添加空格。
void Foo(char bar,int x,int y);//不好
void Foo(char bar, int x, int y);//好
l
推荐不要在实际参数之间添加空格。
Foo( MyChar,0,1 );//不好
Foo(MyChar,0,1);//好
×
不要在函数和’(‘之间添加空格。
Foo ();//不好
Foo();//好
×
不要在’[‘之后和’]’之前添加空格。
X = dataArray[ index ];//不好
X = dataArray[index];//不好
l
推荐在二元操作符之前或之后添加空格。
if(x==y)// 不好
// 好
if(x == y)
a = 0;
a = b;
a >>= 2;
a = b ^ 2;
×
不要在一元操作符之前或之后添加空格。
if(! x)//不好
// 好
if(!x)//好
if (a->b)
*p = 'a';
flag = !isEmpty;
√ 要求模板函数
/类的泛型类型的关键字使用typename,不要使用class。
//不好
template<class T>
inline Max(const T& x1, const T& x2)
//好
template<typename T>
inline Max(const T& x1, const T& x2)
√ 要求模板函数
/类的书写风格如下:
template<typename T>
class MyTemplate
{
void Method1();
template<typename TParam>
void Method2(const TParam& param);
}
template<typename T>
inline Max(const T& x1, const T& x2)
l
推荐不要在代码实现中添加注释。
例外:说明某个复杂的算法
√ 要求为
向外部模块
/
包暴露的接口、类、函数、变量等添加注释。
更多的注释方法请参考
附录B。
例如,
//! Call native method
extern void CallNativeMethod();
/*! /interface IExporter
For the usage of exporting the file to PDF/PS/XML etc.
*/
interface IExporter
{
…
}
/*! /class Exporter
For the usage of exporting the file to PDF/PS/XML etc.
*/
class Exporter : public IExporter
{
…
}
√ 要求遵守
命名规范。
×
不要使用魔数
(Magic Number) 。
√ 要求常量的命名全部使用大写。
例如,
const int MaxPath = 256;//不好
const int Max_Path = 256;//不好
const int maxpath = 256;//不好
const int MAXPATH = 256;//好
×
不要使用
#define而是使用const来定义常量。
例如,
#define MAXPATH 256//不好
const int MAXPATH = 256;//好
√ 要求使用枚举值/static const来定义类中的常量。
例如,
//不好
class Document
{
public:
Document()
: VIID(1000)
{
}
const int VIID;
}
//好
class Document
{
public:
enum {VIID = 1000};
}
//
class Document
{
public:
static const int VIID = 1000;
}
l
推荐不要使用全局变量。
l
推荐不要使用static局部变量。
√ 要求所有的成员变量/局部变量都要进行初始化。
例如,
class Documents
{
public:
Documents()
: m_documentCount(0) //初始化
{
}
void NewDocument(const wchar_t* fileName)
{
bool successful = false;//初始化
…
}
private:
int m_documentCount;
}
l
推荐变量的声明和初始化能够一次完成的尽量一次完成。
//不好
int childCount = 0
childCount = pParent->GetChildCount();
//好
int childCount = pParent->GetChildCount();
×
不要使返回一个局部变量的引用。
例如,
Child* CreateChild()
{
Child child;
Return &child;//不好
}
l
推荐变量只在使用之前进行定义,不要把变量定义都放在函数的开头。
//不好
void BubbleSort(int dataArray[],int count)
{
int i = 0;
int j = 0;
int temp = 0;
for(i = count-1;i > 1; ++i)
{
for(j = 0; j < i; ++ j)
{
}
}
}
//不好
void BubbleSort(int dataArray[],int count)
{
for(int i = count-1;i > 1; ++i)
{
for(int j = 0; j < i; ++ j)
{
}
}
}
×
不要使用布尔变量直接和
0、1进行比较。
//不好
if (flag == 0)
if (flag == 1)
//好
if (flag)
if (!flag)
l
推荐判别指针变量是否为空采用下面的方式。
if (p)
if (!p)
×
不要使用强制类型转换,如果会损失精度或导致不可预测的行为。
×
不要强制转化
const指针变量到non-const。
l
推荐使用const_cast和static_cast来实行强制类型转换,如果强制类型转换是必需的。
l
推荐尽量少使用指向指针的指针或指针数组。
×
不要使用
malloc/free,而要使用new/delete来申请/释放内存。
//不好
int* p = (int*)malloc(sizeof(int));
free(p);
p = 0;
//好
int* p = new int;
delete p;
p = 0;
√ 要求delete一块内存的时候,将指向这块内存的指针设置为空。
//不好
delete p;
//好
delete p;
p = 0;
√ 要求使用new[]分配的内存,要使用delete[]进行释放。
//不好
int* p = new int[100];
delete p;
p = 0;
//好
int* p = new int[100];
delete[] p;
p = 0;
×
不要跨模块释放和释放内存。
不好的方式,例如:
//模块A中
Page* AllocPage()
{
…
return new Page;
}
//模块B中
Page* pNewPage = AllocPage();
delete pNewPage;
pNewPage = 0;
l
推荐少使用/不使用goto语句。
√ 要求优先使用前置的++/--,如果前置和后置的++/--的结果一致。
//不好
for(int i = 0;i < MAXCOUNT; i++)
//好
for(int i = 0;i < MAXCOUNT; ++i)
√ 要求将最短的循环放在最外层、最长的循环放到最内层,如果存在多重循环。
//不好
for(int row= 0; row < 100; ++row)
{
for(int col= 0; col < 5; ++ col)
{
}
}
//好
for(int col= 0; col < 5; ++ col)
{
for(int row= 0; row < 100; ++row)
{
}
}
√ 要求将逻辑判断移到循环体的外面,如果循环体内部存在逻辑判断且循环次数很大。
//不好
for(int i = 0; i < LARGECOUNT; ++i)
{
if (condition)
DoSomething();
else
DoOtherThing();
}
//好
if (condition)
{
for(int i = 0; i < LARGECOUNT; ++i)
DoSomething();
}
else
{
for(int i = 0; i < LARGECOUNT; ++i)
DoOtherThing ();
}
√ 要求每个case语句的结尾都要加上break。
例外:由于逻辑需要,需要重叠多个case分支。
√ 要求default语句的结尾都要加上break。
√ 要求在构造函数中对成员进行初始化,成员初始化的顺序同成员的声明顺序。
例如,
class PointF
{
public:
//好
PointF ()
: m_x(0.0F),
m_y(0.0F),
{…}
//不好
PointF ()
: m_ y(0.0F),
m_x(0.0F),
{…}
private:
double m_x;
double m_y;
}
√ 要求在operator=中检测右操作符和当前对象指向同一个地址。
例如,
Color& operator=(const Color& other)
{
if ((void*)&other == this) {return *this;} //好
…
}
√ 要求在operator=重载中返回*this。
例如,
struct Color
{
public:
Color& operator=(const Color& other)
{
if ((void*)&other == this) {return *this;} //好
…
return *this; //好
}
private:
char m_componets[8];
}
本文详细介绍了C++编码规范,包括书写风格、模板书写、注释、标识符命名、常量、变量、类型转换、内存管理、控制语句和函数等多个方面。规范强调了良好的代码风格、避免使用魔法数字、合理使用注释、正确处理内存分配和释放,以及优化循环结构等最佳实践。
1274

被折叠的 条评论
为什么被折叠?



