服务端组件C++代码规范

前言:

规则的作用是避免混乱,每个人的代码风格都不一样,但是一个团队如果没有统一的标准,后续人员进行二次开发或者维护效率会比较低。

  1. 命名规则

1.1类型命名

类型名称的每个单词首字母均大写, 不包含下划线: Game,GameLogic。

变量命名第一个首字母小写,后面大写:tmpHandCardList,chairId。

成员变量在变量命名的基础上加m_:m_handCards, m_curChairId。

函数名的每个单词首字母大写 , “驼峰变量名如:HandleOutCardOpcode。

宏的命名,全大写,下划线分割:MY_MACRO_THAT_SCARES_SMALL_CHILDREN.

1.2 缩写

函数命名, 变量命名, 文件命名要有描述性; 少用缩写.

尽可能使用描述性的命名, 别心疼空间, 毕竟相比之下让代码易于新读者理解更重要. 不要用只有项目开发者能理解的缩写, 也不要通过砍掉几个字母来缩写单词.

 

错误示例:

int n;                     // 毫无意义.

int nerr;                  // 含糊不清的缩写.

int n_comp_conns;          // 含糊不清的缩写.

 

正确示例:

int baseScore;     // 无缩写

int endPlayerNum;            // "num" 是一个常见的写法

 

一些特定的广为人知的缩写是允许的, 例如用 表示迭代变量.

使用单层循环的时候可以使用i缩写,即使使用i,循环的作用也一目了然。

for (int i = 0; i < GAME_PLAYER; i++)

{

if(i==m_turnWinChairId)

{

return;

}

}

 

注:,但是使用多层循环的时候最好使用带有实际意义的变量名,如

for (int chairId = 0; chairId < GAME_PLAYER; chairId ++)

{

for(int tmpIndex=0; tmpIndex<m_handCards[chairId].size();tmpIndex++)

{

if(m_handCards[chairId][tmpIndex]==0X12)

{

}

}

}

假如此时再使用i,会使得代码的可读性变得非常差。

1.3变量的声明和定义

基本的原则:尽可能小的作用域中声明变量, 离第一次使用越近越好. 这使得代码浏览者更容易定位变量声明的位置

但也有特殊的情况。

// 低效的实现

for (int i = 0; i < 1000000; ++i)

{

    Foo f;                  // 构造函数和析构函数分别调用 1000000 !

    f.DoSomething(i);

}

 

// 效的实现

Foo f;                      // 构造函数和析构函数只调用 1

for (int i = 0; i < 1000000; ++i)

{

    f.DoSomething(i);

}

 

应使用初始化的方式替代声明再赋值

int i;

i = f(); // ——初始化和声明分离

 

int j = g();  // ——初始化时声明

 

 

 

 

 

 

  1. 函数

*大括号另起一行

2.1函数的参数顺序为: 输入参数在先, 后跟输出参数. 在排列参数顺序时, 将所有的输入参数置于输出参数之前.特别要注意, 在加入新参数时不要因为它们是新参数就置于参数列表最后, 而是仍然要按照前述的规则, 即将新的输入参数也置于输出参数之前.

2.2尽量编写简短, 凝练的函数. 如果函数超过 40 , 可以思索一下能不能在不影响程序结构的前提下对其进行分割.即使一个长函数现在工作的非常好, 一旦有人对其修改, 有可能出现新的问题, 甚至导致难以发现的 bug. 使函数尽量简短, 以便于他人阅读和修改代码. 分割为更简短的函数更易于管理和维护.

  1. 注释

*注释推荐使用//

*在代码块前写注释

最好的代码应当本身就是文档. 有意义的类型名和变量名, 要远胜过要用注释解释的含糊不清的名字,但是实际上写代码的时候总会有一些因素会导致部分代码较为难懂,注释作为一种补充,虽然写起来很痛苦, 但对保证代码可读性至关重要.回想一下你在阅读一份没有注释的代码时的痛苦,所以不要吝啬。

 

3.1每个类的定义都要附带一份注释, 描述类的功能和用法, 除非它的功能相当明显.GameGameLogic这种就不需要,自己定义新的classstruct时需要定义。

3.2每个类数据成员 (也叫实例变量或成员变量) 都应该用注释说明用途. 如果变量类型与变量名已经足以描述一个变量, 那么就不再需要加上注释.bool m_maskRevolutionFlag[GAME_PLAYER] 玩家选择革命的标志,这种游戏特有的变量需要注释,而 uint8_t endPlayerCount;明显能从名称看出是结束玩家数量,就不需要写注释

3.3每个函数声明处前都应当加上注释, 描述函数的功能和用途. 只有在函数的功能简单而明显时才能省略这些注释(例如, GetCardLogicValue()).

3.4函数定义处,如果函数的实现过程中用到了很巧妙的或者很复杂的方式, 那么在函数定义处应当加上解释性的注释. 例如, 你所使用的编程技巧, 实现的大致步骤

3.5逻辑较为复杂的部分或者多层循环的时候,以及使用了位操作等较为少见的操作时,需要注释,如。

 

//通过玩家手牌是否空和是否被闷寻找下一个出牌的chairid

for(uint16_t i = 1; i < GAME_PLAYER;i++)

{

uint16_t tmpChairId = (chairId + i) % GAME_PLAYER;

if(m_handCards[i].size()>0&&!m_playerMenFlag.test(i))

return tmpChairId;

}

3.6如果函数参数的意义不明显,可以增加参数注释增加代码的可读性。

3.7错误例子:

// 寻找vector中的element元素

auto iter = std::find(v.begin(), v.end(), element);

if (iter != v.end())

{

  Process(element);

}

这种显而意见的地方就不需要注释。

总之,在不通用,比较冷门,逻辑复杂的地方写上注释,相信大家只要稍微花上一点心思,就可以令代码的可读性更好。

  1. 总结

因为写代码时遇到各种情况,肯定做不到100%规范,希望大家的代码风格往规范上靠拢,如果有好的建议或者规范中有不好的地方,也欢迎大家一起讨论。

posted on 2020-08-20 23:21  长岛的雪  阅读(175)  评论(0编辑  收藏  举报