C和C++编码规范.doc

上传人:jian****018 文档编号:9041695 上传时间:2020-04-02 格式:DOC 页数:80 大小:502KB
返回 下载 相关 举报
C和C++编码规范.doc_第1页
第1页 / 共80页
C和C++编码规范.doc_第2页
第2页 / 共80页
C和C++编码规范.doc_第3页
第3页 / 共80页
点击查看更多>>
资源描述
C C 编码规则 文档编号 当前版本 V1 0 作 者 制作部门 终端软件研发部 文件状态 草稿 公开类型 内部公开 完成日期 2012 年 07 月 08 日 编写与修改记录 版本号 完成日期 更改位置 更改内容 编制 修改 审批 V1 0 2012 07 08 全文 初稿 目 录 章节目录 第 1 章 前言 7 第 2 章 RULECHECKER 规则集 7 2 1 基本规则集 7 2 1 1 ansi 函数的声明和定义要遵守 ANSI 规定的格式 7 2 1 2 asscal 在函数调用语句中不要使用赋值操作符 8 2 1 3 asscon 不要在控制语句的条件表达式中使用赋值操作符 9 2 1 4 assexp 赋值表达式中的规定 9 2 1 5 blockdecl 在语句块的头部定义变量 10 2 1 6 boolean 使用正确格式的布尔表达式 10 2 1 7 brkcont 程序中禁用 break continue 11 2 1 8 classuse 对未知类成员的使用 11 2 1 9 cmclass 一个源文件只对应一个类 12 2 1 10 cmdef 源文件中不要有类的声明 12 2 1 11 condop 关于 操作符 12 2 1 12 const 使用常量 13 2 1 13 constrcpy 关于拷贝构造函数 14 2 1 14 constrdef 关于默认构造函数 14 2 1 15 ctrlblock 清晰划分控制语句的语句块 15 2 1 16 destr 关于析构函数 15 2 1 17 dmaccess 类数据成员的访问控制 16 2 1 18 exprcplx 表达式的复杂性 16 2 1 19 exprparenth 在表达式中使用括号 17 2 1 20 fntype 必须为函数返回值指定类型 18 2 1 21 frndclass 关于友员的声明位置 18 2 1 22 funcres 设置禁止使用的函数 18 2 1 23 goto 禁用 Goto 语句 19 2 1 24 Headercom 对文件注释的要求 20 2 1 25 headercom 函数 类的注释 21 2 1 26 hmclass 一个头文件中只声明一个类 21 2 1 27 hmdef 头文件中只包含声明 不应包含实现 21 2 1 28 hmstruct 避免重复包含头文件 22 2 1 29 identfmt 对命名的要求 23 2 1 30 identl 对标识符长度的要求 23 2 1 31 identres 设置禁止使用的标识符 24 2 1 32 imptype 明确指定类型 24 2 1 33 incltype 设置可包含的文件 24 2 1 34 inldef 关于内联函数的声明和定义 25 2 1 35 macrocharset 在宏中禁用某些字符 25 2 1 36 macroparenth 括号在宏中的使用 26 2 1 37 mconst 限制宏常量的使用 26 2 1 38 mfunc 用内联函数代替宏函数 27 2 1 39 mname 文件命名 28 2 1 40 multiass 一条程序语句中只应包含一个赋值操作符 29 2 1 41 nopreproc 限制使用编译指令 29 2 1 42 nostruct 不要使用结构体 30 2 1 43 notemplate 不要使用模板 30 2 1 44 nothrow 不要抛掷异常 30 2 1 45 nounion 不要使用联合体 30 2 1 46 operass 为类重载 操作符 31 2 1 47 parammode 明确标识出函数参数的类型 31 2 1 48 parse 分析错误 32 2 1 49 ptraccess 指针指向的数据成员的访问方式 32 2 1 50 ptrinit 对指针的初始化 32 2 1 51 sectord public private 和 protected 的声明顺序 33 2 1 52 sgancstr 拥有共同的基类 35 2 1 53 sgdecl 一次只声明 定义一个变量 35 2 1 54 sglreturn 一个函数应该只有一条 return 语句 35 2 1 55 slcom 注释使用 36 2 1 56 slstat 一行只写一条语句 36 2 1 57 swdef switch 语句中的 default 分支 37 2 1 58 swend 对 switch 语句中每个分支结尾的要求 37 2 1 59 typeinher 明确指明派生类与基类的关系 38 2 1 60 typeres 设置禁用的类型 38 2 1 61 vararg 禁止函数使用可变数量的参数 39 2 1 62 varstruct 关于定义 struct union 变量 39 2 2 SCOTT MEYERS 规则集 40 2 2 1 assignthis 在 操作符定义中检查是否自己赋值给自己 40 2 2 2 cast Prefer 尽量使用 C 风格的类型转换 41 2 2 3 catchref 通过引用捕获异常 41 2 2 4 constrinit 尽量在构造函数的初始化列表中对数据成员初始化 42 2 2 5 convnewdel 重载 new delete 操作符时应遵守的约定 42 2 2 6 dataptr 指针数据成员 43 2 2 7 delifnew 如果你重载了操作符 new 也应该重载操作符 delete 43 2 2 8 excepspec 审慎使用异常处理 43 2 2 9 inlinevirt 内联虚拟函数 43 2 2 10 multinher 尽量不要使用多继承 44 2 2 11 nonleafabs 将非末端类设计为抽象类 44 2 2 12 normalnew 不要遮掩了 new 的正规形式 45 2 2 13 overload 不要重载 f void f a b int a char b f int char f 2 1 2 asscal 在函数调用语句中不要使用赋值操作符 规则描述 函数调用语句中 在函数的参数列表中不要使用赋值操作符 赋值操作 符包括 0 i j if x dx for i j n i 0 j 2 1 4 assexp 赋值表达式中的规定 规则描述 在一个赋值表达式中 一个左值 在表达式中应该仅被赋值一次 对于多重赋值表达式 一个左值在表达式中仅应出现一次 不能重复出 现 目的 避免产生不明确的赋值顺序 举例 正确写法 错误写法 b c a a b a b c a 2 1 5 blockdecl 在语句块的头部定义变量 规则描述 变量的定义要出现在使用该变量的语句块的开头 目的 提高代码的可读性 2 1 6 boolean 使用正确格式的布尔表达式 规则描述 对于 if while for 等控制语句的布尔表达式 要使用正确的格式 目的 使代码更容易理解 举例 正确写法 错误写法 AlwaysTrue true while AlwaysTrue true if test true for i 1 function call i true i while 1 if test for i 1 function call i i 2 1 7 brkcont 程序中禁用 break continue 规则描述 在控制语句 for do while 块中 禁止使用 Break 和 continue 不 过 在 switch 语句块中 可以使用 break 目的 和 goto 语句一样 使用 Break 和 continue 会打乱代码结构化的流程 在循环语句块中禁用 goto Break 和 continue 会增加代码的可读性 2 1 8 classuse 对未知类成员的使用 规则描述 在代码中不要使用如下形式的表达式 u v a u v f u g a u g f 也不要有使用 操作符的类似形式的表达式 目的 防止类对象通过多级的 操作符 调用未知的成员函数 数 据成员 类与类之间的接口应该清晰 举例 不要象下面这样写代码 myWindow itsButton push 其中 对象 myWindow 的基类为类 Window itsButto 是 Window 的一个公 共数据成员 它也是一个类对象 itsButto 有一个叫做 push 的公共成员函 数 我们应该清楚的是 类 Window 才是 myWindow 访问其的接口 myWindow 只 应访问到 itsButton 而不应该访问到 itsButton push 这一级 因为 push 已经不属于基类 Window 对 myWindow 的接口 再举一个例子 Error pos line 这和上面例子的道理一样 只是这一次由访问成员函数变为了访问数据 成员 line 这同样是不好的 2 1 9 cmclass 一个源文件只对应一个类 规则描述 在一个源文件中定义的每一个函数 都应该属于同一个类 即对一个类 的描述要独占一个文件 其中 源文件指以 cc cxx cpp C or c 为后缀的代码文件 参数 可供选择的字符串 包括 cc cxx cpp C or c 用来设置 检查什么类型的代码文件 目的 提高代码的可读性 2 1 10cmdef 源文件中不要有类的声明 规则描述 在一个源文件中不应该包含任何类的声明 而只应该是对类的实现 类 声明应该统一放到头文件中去 其中 源文件指以 cc cxx cpp C or c 为后缀的代码文件 参数 可供选择的字符串 包括 cc cxx cpp C or c 用来设置 检查什么类型的代码文件 目的 提高代码的可读性 2 1 11condop 关于 操作符 规则描述 程序中不要使用三元运算符 目的 提高代码的可读性 2 1 12const 使用常量 规则描述 程序中的数字和字符串 都要显示的声明 定义为常量 在 RuleChecker 默认的情况下 只允许程序中直接出现下面这四个数字和字符串 量 它们分别是 空字符串 只包含一个空格的字符串 0 数字 0 和 1 数字 1 其它任何的数字和字符串 都要定义为常量 参数 可供选择的字符串 用来指出那些允许在程序中直接出现 而不必以常 量定义的数字和字符串 目的 这样做可以避免数字和字符串零散分布在代码中 使代码修改起来相当 费力 遵守这项规则可以提高代码的可维护性 注意 在对某些量的初始化列表中 比如数组 结构体 RuleChecker 仅会对 其前 5 个数据成员依照该项规则进行检查 举例 正确写法 错误写法 define TAB SIZE 100 enum i val ok 7 ko 11 const char HelloWorld Hello World n char tab TAB SIZE i val i if i ok p HelloWorld char tab 100 int i if i 7 p Hello World n 2 1 13constrcpy 关于拷贝构造函数 规则描述 每一个类都应该显示的定义拷贝构造函数 参数 参数只有一个 要么为空 要么为字符串 dynalloc 如果设置参数为 dynalloc 那么 RuleChecker 仅在当类中包含指针类型的数据成员时 才要 求类要显示定义拷贝构造函数 如果设置参数为空 则不管类中包含什么样的 成员 都要显示定义拷贝构造函数 目的 确保类的编写者考虑类对象在被拷贝时可能出现的各种情况 举例 class aClass aClass const aClass const 并不是必须的 2 1 14constrdef 关于默认构造函数 规则描述 每一个类都应该显示的定义默认构造函数 目的 确保类的编写者考虑类对象初始化时可能出现的各种情况 举例 class aClass aClass 2 1 15ctrlblock 清晰划分控制语句的语句块 规则描述 控制语句 if for while do whule 的语句部分一定要用 和 括起来 以划分出清晰的语句块 目的 这样做 能够使语句的归属明确 使代码更加容易阅读和修改 举例 正确写法 错误写法 if x 0 return else while x min x if x 0 return else while x min x 2 1 16destr 关于析构函数 规则描述 每一个类都应该显示的定义析构函数 目的 确保类的编写者考虑类对象在析构时 可能出现的各种情况 举例 class aClass aClass aClass 2 1 17dmaccess 类数据成员的访问控制 规则描述 类对外的接口应该是完全功能化的 也就是类中可以定义 Public 的成员 函数 但不应该有 Public 的数据成员 在 RuleChecker 默认情况下 会检查类中是否声明了 Public 数据成员 如果有 则视为违反了该条规则 参数 参数是 public protected privatr 这三个字符串 通过指定相应的字 符串 RuleChecker 就会禁止类中声明与之相对应的数据成员 目的 要想改变对象的当前状态 应该通过它的成员函数来实现 而不应该通 过直接设置它的数据成员 一个类的数据成员应该声明为 private 的 最起码 也应该是 protected 的 2 1 18exprcplx 表达式的复杂性 规则描述 对于表达式的复杂性 要有一定的限制 表达式的复杂性通过一个叫做 关联语法树 associated syntactictree 的指标来衡量 它的计算方法为 表达式中操作符的数量加上操作数的数量再加 1 在 RuleChecker 默认情况下 表达式复杂性的上限被设定为 13 参数 是一个数字 用来指定表达式复杂性的最大可接受程度 目的 提高代码的可读性 举例 对于下面这个表达式 b c d b f c d 它包含了 8 个操作符 7 个操作数 因此该表达式关联语法树为 16 如 果你设定的参数的上限小于等于 16 则 RuleChecker 会认为此表达式违反了该 条规则 2 1 19exprparenth 在表达式中使用括号 规则描述 对于一个表达式 在每一个二元 三元操作的开始和结束处 都要放置 和 在 RuleChecker 中 我们可以通过放置 partpar 参数来减少一些限制 放置 partpar 参数后 当在操作符 或 右边的操作数的右边又使用了 或 操作符时 可以不放置 和 对赋值操作符右边的操作数 可 以忽略 和 在表达式的最外层也可以忽略 和 除此 之外的其它情况 都要放置 和 在 RuleChecker 默认情况下 参数 partpar 被设置 参数 参数为字符串 partpar 如果放置了该参数 则 RuleChecker 不按照最 严格的要求检测代码 而是按我们上面提到的要求来检测代码 否则 按照最 严格的要求检测代码 目的 避免出现不明确的运算 赋值顺序 举例 正确写法 错误写法 result fact 100 rem 当放置了 partpar 参数时 也可以写成这样 result fact 100 rem 当放置了 partpar 参数时 可以用下面的写法 result fact ind 100 rem 10 coeff c 代替如下的写法 result fact ind 100 rem 10 coeff c result fact 100 rem 2 1 20fntype 必须为函数返回值指定类型 规则描述 要为每一个函数指定它的返回值类型 如果函数没有返回值 则要定义 返回类型为 void 目的 改善代码的可移植性 2 1 21frndclass 关于友员的声明位置 规则描述 如果将一个 或若干个 类声明为另一个类的友员 则必须将这个 这 些 友员声明放在类所有数据成员声明的最前面 2 1 22funcres 设置禁止使用的函数 规则描述 禁止在程序中声明 定义 调用我们指定函数名的函数 在 RuleChecker 默认情况下 不禁用任何的函数名 参数 参数是一系列的字符串列表 其中的每个字符串就是在程序中要禁用的 函数的名字 目的 通过禁用一些只与特定平台相关联的函数 可以提高程序的可移植性 除此之外 你还可以通过设定该规则来实现一些其它的目的 比如禁用某些极 易导致程序发生错误的函数 等等 举例 如果我们设置了在程序中禁用函数 fun int nCount 则在代码中出现 下面的任何一种情况 RuleChecker 都会认定程序违反了该条规则 Void fun int nCount 声明 Void fun int nCount 定义 fun 1 调用 2 1 23goto 禁用 Goto 语句 规则描述 程序中不要使用 goto 语句 在 RuleChecker 默认情况下 出现在程序任 何地方的 goto 语句都是被禁止的 不过 我们可以通过设置 使得 goto 跳转 到我们指定的语句行号的语句为合法 参数 参数是一个字符串的列表 每个字符串都代表一个语句行号 表示允许 在程序中通过 goto 跳转到该语句行号 目的 这条规则的目的是为了确保程序的结构化 因为滥用 goto 语句会使程序 流程无规则 可读性差 Goto 语句只在一种情况下有使用价值 就是当要从多重循环深处跳转到 循环之外时 效率很高 但对于一般要求的软件 没有必要费劲心思追求多么 高的效率 而且效率主要是取决于算法 而不在于个别的语句技巧 2 1 24Headercom 对文件注释的要求 规则描述 在头文件 实现文件的首部一定要有文件注释 在 RuleChecker 中 我们还可以规定这个文件注释的具体格式 在 RuleChecker 默认情况下 头文件和实现文件的文件注释中必须包括 文件名 开发者 开发日期 功能简介这四部分 都是以英文表示的 见下面 的示例 我们也可以设置成中文 参数 参数由两个字符串列表来表示 第一部分是对头文件的文件注释格式要 求 第二部分是对实现文件的文件注释格式要求 每个列表都是以 HEADER 或 CODE 开头 后面是对注释格式的具体描述 目的 提高代码的可读性 举例 下面是一个符合 RuleChecker 默认的对头文件文件注释格式要求的例子 Name program Author Andrieu Date 08 07 96 Remarks example of comments 2 1 25headercom 函数 类的注释 规则描述 在全局 静态函数的声明 定义和类的声明 定义之前 要对该函数或 类加以注释 在 RuleChecker 中 我们还可以规定这个文件注释的格式 RuleChecker 默认情况下 在函数或类之前必须有以 开头的注释 注释内容不限 参数 参数是五个字符串列表 这五个字符串列表分别以 class func glob def func glob decl func stat def func stat decl 开头 分别代表声明类 定义全局函数 声明全局函数 定义静态函数 声明 静态函数 后面跟着的就是对注释格式的具体要求 目的 提高代码的可读性 2 1 26hmclass 一个头文件中只声明一个类 规则描述 在一个头文件中 只应该包含对一个类的声明 嵌套类的情况除外 RuleChecker 默认情况下 头文件是指以 h hh H hxx hpp 为后缀的文 件 参数 参数是可供选择的字符串 比如 h hh H 等 用来设置检查什么类 型的代码文件 目的 提高代码的可读性 2 1 27hmdef 头文件中只包含声明 不应包含实现 规则描述 在头文件中不要定义全局变量和全局函数 在 RuleChecker 默认情况下 头文件指以 h hh H hxx hpp 为后缀的代码文件 参数 参数为可供选择的字符串 包括 h hh H hxx hpp 用来设 置检查什么类型的代码文件 目的 在头文件中只应该包含各种声明 而不应该包含具体的实现 2 1 28hmstruct 避免重复包含头文件 规则描述 头文件的格式应该为 ifndef define endif 或者 if defined define endif 上面的是一个标识字符串 RuleChecker 要求在该标识字符串中 必须包含相应头文件的文件名 不区分大小写 参数 参数有两个 一个用于设置标识字符串的长度 另一个参数设置检查什 么类型的代码文件 目的 避免对同一头文件的重复包含 举例 对于文件 audit h 它的文件结构应该为 ifndef AUDIT H define AUDIT H endif 2 1 29identfmt 对命名的要求 规则描述 在程序中声明 定义的函数 自定义数据类型 变量 在对其命名时都 应该遵守一个统一的命名规范 在 RuleChecker 默认情况下 只规定在常量 宏中不能使用小写的英文 字母 参数 参数是一系列的字符串 单数编号字符串指出了你要设定的对象 双数 字符串指出了你为其设定的具体格式 目的 提高代码的可读性 2 1 30identl 对标识符长度的要求 规则描述 在程序中声明 定义的函数 自定义数据类型 变量 它们的名称的长 度要在设定的范围之内 RuleChecker 默认情况下规定 函数名长度在 4 到 25 个字符之间 自定 义数据类型名 变量名 常量名 宏名 类名长度在 5 到 25 个字符之间 其它 标识符的长度在 1 到 25 个字符之间 参数 参数分三列 第一列指出了你要设定的对象 第二列 第三类指出了命 名的长度范围 目的 提高代码的可读性 2 1 31identres 设置禁止使用的标识符 规则描述 某些标识符在代码中应该被禁用 比如 类库中的某些数据成员的名字 在 RuleChecker 默认情况下 不禁用任何标识符 参数 参数是一系列的字符串列表 其中的每个字符串就是在程序中要禁用的 标识符 目的 改善代码的可移植性 2 1 32imptype 明确指定类型 规则描述 要明确指定函数 函数参数 类数据成员 变量的类型 目的 改善代码的可移植性 举例 正确写法 错误写法 void aFunction void aFunction 2 1 33incltype 设置可包含的文件 规则描述 只允许在指定类型的代码文件中包含其它代码文件 在 RuleChecker 默认情况下 只允许头文件被包含到其它代码文件中去 参数 参数为两个字符串列表 每个列表中的第一个字符串指定了目标文件的 类型 第二个字符串指出了都有那些类型的文件可以被包含到该目标文件中去 目的 改善程序代码的组织结构 2 1 34inldef 关于内联函数的声明和定义 规则描述 内联函数的定义部分 要放到类的实现文件 cpp 中去 而不要直接 放在头文件中 参数 参数只有一个 字符串 private 该参数可以用也可以不用 当放置了 private 这个字符串时 private 型内联函数的定义要放到 类的实现文件 cpp 中去 其它内联函数的定义要放在头文件中 当没有放 置这个字符串时 所有的内联函数的定义部分 都要放到实现文件 cpp 中 去 目的 提高代码的可读性 该规则存在的问题 放置参数 private 后并不起作用 不管是否放置了 private 字符 串 该规则都会要求将所有内联函数的定义放到实现文件 cpp 中去 2 1 35macrocharset 在宏中禁用某些字符 规则描述 可以在宏中 这里的宏只包括宏函数和宏常量这两类宏 并且检查部分 只是指宏的展开部分 而不包括宏的名字 禁用某些字符 在 RuleChecker 默认情况下 不禁用任何字符 参数 参数为两对相互关联的字符串 第一对字符串是针对宏常量的 第二对 字符串是针对宏函数的 要禁用哪些字符 就把这些字符添加到字符串中去 目的 改善代码的可移植性 2 1 36macroparenth 括号在宏中的使用 规则描述 对于宏的展开部分 在宏的参数出现的地方要加括号 目的 保证宏替换的安全 同时提高代码的可读性 举例 正确写法 错误写法 define GET NAME obj ind obj name ind define GET NAME obj ind obj name ind 2 1 37mconst 限制宏常量的使用 规则描述 宏常量的使用要受到限制 在 RuleChecker 中 有三个可选的设置 var 当设定该参数时 字符串不能用宏常量来表示 其它的数值不受 限制 举例 正确写法 错误写法 const char string Hello world n define value 3 define string Hello world n const 当设定该参数时 一律要求使用 const 来定义数值常量 禁止 使用通过宏来替代数值的方法 举例 正确写法 错误写法 const char string Hello world n const int value 3 define string Hello world n define value 3 nodefine 当设定该参数时 程序中只允许使用宏函数和预编译指令 其它任何的宏均禁止使用 举例 正确写法 错误写法 define VERBOSE define min x y x fld 的形式代替 ptr fld 的形式 2 1 50ptrinit 对指针的初始化 规则描述 在定义指针变量的同时 就要对其进行初始化 目的 保证指针变量在被使用前已经被初始化 举例 正确格式 错误格式 int y int y y 2 1 51sectord public private 和 protected 的声明顺序 规则描述 在类声明中 要将处于不同访问控制级别的类成员 按照指定的顺序声 明 参数 参数为一个字符串列表 其中可以包括 private protected public 这四个字符串 private protected public 三个字符串分别代表 private protected public 访问控制级别的类成员 空字符串 表示未明确 指出访问控制级别的类成员 未明确指出的访问控制级别被默认为 private 在列表中出现的字符串 表示允许在类声明中出现的访问控制级别 列 表中字符串的顺序 表示对声明不同访问控制级别的类成员的声明顺序要求 RuleChecker 默认情况下该参数为空 目的 提高代码的可读性 举例 如果我们这样设置了参数 private protected public 则表示我们允许在类 中声明 private protected public 访问控制级别的成员 且声明的顺序依次是 默认 访问控制级别成员 private 成员 protected 成员 public 成员 对于声明的顺序 并不 要求必须完整包括这四部分 声明顺序可以只是 protected 成员 public 成员 或者是 private 成员 public 成员 等等 正确写法 错误写法 class aClass 顺序为 private protected public int i private void p1 protected void p2 public void p3 class aClass 顺序为 protected int i protected void p class aClass 顺序为 protected public class aClass 颠倒了 private 和 protected 的顺序 不符合要求 protected private protected int i public void p 2 1 52sgancstr 拥有共同的基类 规则描述 在整个系统中 应该有一个类作为所有其它类的直接或间接父类 参数 参数为一个字符串 来指定这个超级基类的名字 2 1 53sgdecl 一次只声明 定义一个变量 规则描述 一次 一条声明 定义语句 只声明 定义一个变量 目的 提高代码的可读性 举例 正确写法 错误写法 int width int length int width length 2 1 54sglreturn 一个函数应该只有一条 return 语句 规则描述 一个函数中应该只有一条 return 语句 目的 增加函数的可靠性 使代码更容易理解 疑义 RuleChecker 在对这条规则的实现上不太完善 它只是机械的检查 return 的个数 比如对于如下的代码 void CMyClass Fun1 int a if a 10 return a 实际是有两个出口 但 RuleChecker 却认为其合格 2 1 55slcom 注释使用 规则描述 对代码的注释一律使用 禁止使用 目的 提高代码的可读性 2 1 56slstat 一行只写一条语句 规则描述 一行只写一条程序语句 目的 提高代码的可读性 举例 正确写法 错误写法 x x0 y y0 while IsOk x x x x0 y y0 while IsOk x x while IsOk x x 2 1 57swdef switch 语句中的 default 分支 规则描述 在 switch 语句块中 一定要有 default 分支来处理其它的情况 参数 参数只有一个 要么为空 要么为字符串 last 如果设置参数为 last 则要求 default 分支出现在 switch 语句块的最后 如果不设置这个参 数 则 switch 语句块中只要有 default 分支即可 RuleChecker 默认情况下参数被设置为 last 目的 用来处理 switch 语句中默认 特殊的情况 2 1 58swend 对 switch 语句中每个分支结尾的要求 规则描述 switch 语句中的每一个 case 分支 都要以 break continue goto return exit 中之一作为分支的结尾 几个连续的 空 case 语句允许共用一个 参数 参数只有一个 要么为空 要么为字符串 nolast 如果设置参数为 nolast 则对最后一个分支不做要求 如果不设置 nolast 则对最后一个 分支做同样的要求 RuleChecker 默认情况下参数被设置为 nolast 目的 使代码更容易理解 减少代码发生错误的可能性 2 1 59typeinher 明确指明派生类与基类的关系 规则描述 在由基类派生子类时 要明确指明派生类对基类的访问控制 public protected private 目的 明确子类 基类的继承关系 举例 正确写法 错误写法 class inherclass public Base1 private Base2 class inherclass2 private Base1 class inherclass1 public Base1 Base2 等价于 public Base1 private Base2 class inherclass2 Base1 等价于 private Base1 2 1 60typeres 设置禁用的类型 规则描述 我们可以禁止在程序中声明 定义某些类型的变量 禁止在程序中声明 定义某些返回类型的函数 在 RuleChecker 默认情况下 不禁用任何类型 注意 当你用 typedef 为某一类型重新定义了一个名字时 则 RuleChecker 不 再能够正确的识别出该类型 参数 参数是两个分别以 data 和 function 开头的字符串列表 以 data 开头的字符串列表表示禁止在程序中声明 定义哪些类型的变量 以 function 开头的字符串列表表示禁止在程序中声明 定义哪些返回类型的 函数 目的 提高程序的可移植性 2 1 61vararg 禁止函数使用可变数量的参数 规则描述 定义 声明一个函数时 在其参数列表中禁止使用 在参数列表中使用 的一个例子 C 函数 printf const char 目的 使代码更容易理解 2 1 62varstruct 关于定义 struct union 变量 规则描述 禁止在程序中直接定义结构体 struct 联合体 union 变量 要使用 typedef 为自定义的结构体 联合体重新命名后 再使用这个名 字来定义变量 目的 使代码更容易理解 举例 正确写法 错误写法 typedef struct typeName typeName varName struct varName 2 2 Scott Meyers 规则集 下面的 19 条编码规则取自 Scott Meyers 写的两本书 Effective C More Effective C 所以我们称它们为 Scott Meyers 编码规则 象前面的基本规则一样 我们逐条来介绍每一条规则 2 2 1 assignthis 在 操作符定义中检查是否自己赋值给 自己 规则描述 在类的赋值操作符的定义中 RuleChecker 会检查 程序是否对参数和 this 或 this 之间进行了 判断 如果进行了这个判断 是否返回了 this 目的 确保在类的赋值操作符的定义中 避免发生自己赋值给自己的这种情况 举例 正确写法 错误写法 class CTest public class CTest public int m 1 CTest CTest m 1 obj1 m 1 return this int m 1 CTest CTest 该规则目前存在的问题 在 RuleChecker 中 该规则不能正确发挥作用 象上面那种存在缺陷的 情况 RuleChecker 并不能检测出来 2 2 2 cast Prefer 尽量使用 C 风格的类型转换 该规则参考自 More Effective C 中的条款 2 规则描述 用 C 提供的类型转换操作符 static cast const cast dynamic cast 和 reinterpret cast 代替 C 风格的类型转换符 目的 C 风格的类型转换符有两个缺点 1 允许你在任何类型之间进行转换 即使在这些类型中存在着巨大的不 同 2 在程序语句中难以识别 2 2 3 catchref 通过引用捕获异常 该规则参考自 More Effective C 中的条款 13 规则描述 让异常通过引用的方式传递到 catch 子句中 目的 改善代码的效率 2 2 4 constrinit 尽量在构造函数的初始化列表中对数据成 员初始化 该规则参考自 Effective C 中的条款 12 规则描述 类中非静态数据成员的初始化操作 一律放到构造函数的初始化列表中 进行 目的 改善代码的效率 2 2 5 convnewdel 重载 new delete 操作符时应遵守的约 定 该规则参考自 Effective C 中的条款 8 规则描述 重载 new 操作符时应遵守的约定 返回值的类型要为 void 第一个参数的类型要为 size t 重载 delete 操作符时应遵守的约定 返回值的类型要为 void 第一个参数的类型要为 void 如果有第二个参数 类型要为 size t 参数 参数只有一个 要么为空 要么为字符串 static 如果设置参数为 static 表示重载 new delete 操作符为类的静态 static 成员 目的 使重载的 new delete 操作符的行为与缺省 new delete 的行为保持一 致 2 2 6 dataptr 指针数据成员 该规则参考自 More Effective C 中的条款 10 规则描述 类中尽量不要包含指向类对象的指针数据成员 目的 一是防止在执行构造函数过程中发生异常而导致内存泄露 二是为了简 化析构函数 2 2 7 delifnew 如果你重载了操作符 new 也应该重载 操作符 delete 该规则参考自 Effective C 中的条款 10 规则描述 如果你为一个类重载了操作符 new 那你也应该为这个类重载操作符 delete 目的 操作符 new 和操作符 delete 需要一起合作 2 2 8 excepspec 审慎使用异常处理 该规则参考自 More Effective C 中的条款 14 规则描述 不要使用异常处理 目的 异常处理的不当使用 经常会导致严重 隐蔽的错误 2 2 9 inlinevirt 内联虚拟函数 该规则参考自 More Effective C 中的条款 24 规则描述 虚拟函数不要被声明为内联 inline 的 目的 改善代码的效率 2 2 10multinher 尽量不要使用多继承 该规则参考自 More Effective C 中的条款 43 规则描述 尽量不要使用多继承 RuleChecker 仅在一种情况下允许使用多继承 多继承中的基类为抽象 类 也就是说在基类中至少要包含一个纯虚函数 目的 减少复杂性 使代码更容易理解 示例 例一 A 和 B 不是抽象类 C 多继承自 A 和 B 则 C 违反此规则 例二 A 和 B 都是抽象类 C 多继承自 A 和 B 则 C 不违反规则 例三 A 是抽象类 B 不是抽象类 C 多继承自 A 和 B 则 C 违反此规则 2 2 11nonleafabs 将非末端类设计为抽象类 该规则参考自 More Effective C 中的条款 33 规则描述 非末端类应该设计为抽象类 在类的继承图中 处于继承图叶子节点上 的类 我们称之为末端类 其他类我们称之为非末端类 目的 提高程序的可靠性 健壮性 可读性 可扩展性 2 2 12normalnew 不要遮掩了 new 的正规形式 该规则参考自 Effective C 中的条款 9 规则描述 如果为一个类重载了一个或几个操作符 new 那么至少要有一个重载 操作支持 new 的正规调用形式 下面是具体的方法 new 的第一个参数类型必须为 size t 为其它的参数提供默认参数值 目的 保证重载了 new 操作符的类 仍然可以正常使用 new 的正规形式 2 2 13overload 不要重载 前缀 const Example operator int 后缀 Example 前缀 const Example operator int 后缀 目的 保证定义的类与 C 内置数据类型操作上的一致性 该规则目前存在的问题 在 RuleChecker 中 该规则并不能正确发挥作用 象上面那样写代码时 RuleChecker 仍会认为违反规则 2 2 15refclass 类的引用 该规则参考自 Effective C 中的条款 22 规则描述 对于类类型的参数 要以引用 by reference 的方式传递 目的 改善代码的效率 2 2 16returnthis 在重载 时 使其返回 this 该规则参考自 Effective C 中的条款 15 规则描述 在为一个类重载 操作符时 必须使其返回 this 目的 如果不返回 this 的话 会防碍我们进行连续赋值 a b c 这种 操作 或是导致类型转换不能正确的实现 2 2 17tryblock Try 语句块 该规则参考自 More Effective C 中的条款 15 规则描述 不要使用异常处理 目的 改善代码的效率 2 2 18trydestr 析构函数中的异常处理 该规则参考自 More Effective C 中的条款 11 规则描述 在析构函数中要考虑发生异常的情况 要包含 try catch 语句块 目的 防止 terminate 被调用 同时确保析构函数能被完整执行 terminate 函数 当我们没有为产生的某一种异常情况提供处理方法 时 terminate 会被调用 这个函数的作用正如其名字所表示的 它终止你 程序的运行 而且是立即终止 并且不会释放局部对象 2 2 19virtdestr 虚拟析构函数 Virtual destructor 该规则参考自 Effective C 中的条款 14 规则描述 基类的析构函数一定要为虚拟函数 virtual Destructor 目的 保证类对象内存被释放之前 基类和派生类的析构函数都被调用 2 2 20assignthis Check for Assignment to self in Operator 规则描述 在赋值操作符的定义中 必须检查两个参数 this 或者 this 是否 相等 如果相等 必须返回 this 目的 确保可以自赋值 2 2 21cast c 风格的类型转换 规则描述 使用 c 风格的类型转换 static cast const cast dynamic cast 和 reinterpret cast 而不是使用 c 风格的类型转换 目的 c 风格的类型转换允许任何类型间的相互转换 而且不容易识别 举例 假设你想把一个 int 转换成 double 以便让包含 int 类型变量的表达式 产生出浮点数值的结果 如果用 C 风格的类型转换 你能这样写 int firstNumber secondNumber double result double firstNumber secondNumber 如果用上述新的类型转换方法 你应该这样写 double result static cast firstNumber secondNumber 2 2 22dataptr 数据的指针类型 规则描述 类成员不允许是对象指针 目的 阻止发生在构造函数和析构函数中的内存泄漏 2 2 23delarray Use square brackets when deleting arrays to ensure full array is deallocated 规则描述 当删除数组时必须使用 目的 确保恰当的内存被释放 举例 正确写法 错误写法 int table new int 7 delete table int table new int 7 delete table delete 10 table 局限 1 该规则 在一些复杂的情况下失效 不起作用 例子 1 int myarray new int 2 myarray 0 new int 10 delete myarray 违反规则 delete myarray 0 不违反规则 例子 2 class A public int tab A var var tab new int 10 delete var tab 不违反规则 局限 2 当 new 操作被隐式使用 则规则不起作用 int create array int nb return new int nb int myarray create array 10 delete myarray 不违反规则 2 2 24exprparenth Parenthesses should be used to indicate evaluation order 规则描述 在表达式中 每个二元的和三元的操作符必须放在 中 如果使用参数 partpar 则 当右边的操作符与当前操作符同是 或者 则 禁止为右边的操作数使用 同上 赋值操作符右边的操作数禁止使用 禁止在表达式的第一级使用 目的 减少运算顺序的不明确性 配置 参数 partpar 举例 正确写法 错误写法 result fact 100 rem result fact 100 rem result fact 100 rem result fact ind 100 result fact ind 100 rem 10 coeff c rem 10 coeff c 2 2 25forinit 循环的计数器 在 for 循环中 必须在循环的初始化语 句段中初始化 规则描述 循环的计数器 在 for 循环中 必须在循环的初始化语句段中初始化 由循环头中的第三个元素来判断哪个是循环计数器 目的 通过这种要求 循环计数器被确保初始化 循环易于理解和控制 例子 正确写法 错误写法 for int i 0 i 10 i for int i i 10 i for int j 0 j 10 i for int j 10 i j i for int j 1 i funct j i j 2 2 26funcptr 不使用函数指针 规则描述 不使用函数指针 例子 1 void print int i std cout i std endl void func 1 int func 1 func 1 1 func 1 1 例子 2 typedef void PFUNC int PFUNC pfunc 2 2 27globinit 全局变量必须在定义的时候初始化 规则描述 全局变量必须在定义的时候初始化 目的 不是所有的编译器都给予相同的默认值 可以通过控制变量的值来避免 一些不期望的动作 当声明全局变量的时候就赋初值可以确保在使用它们之前 初始化 2 2 28multinher Multiple Inheritance Only Allowed for Inheriting Abstract 规则描述 如果使用多继承 被继承的类 父类 必须是抽象的 也就是说 它们 必须要有至少一个纯粹的虚函数 目的 代码易于理解 2 2 29nonleafabs Make non leaf classes abstract 规则描述 非叶节点类一定要是抽象类 目的 提高类的设计 2 2 30nostruct 规则描述 关键字 struct 不允许使用 如果通过参数指明 只有 c 类型的 struct 可以使用 配置 cstruct 允许 c 类型的 struct 可以使用 2 2 31pmfrtn 不返回指针成员数据 规则描述 成员函数一定不能返回一个指针或 non const 引用数据成员 2 2 32refclass 类的引用 规则描述 对于类类型的参数 要以引用 by reference 的方式传递 目的 提高效率 2 2 33rtnlocptr 不能返回一个指向一个非静态局部变量 规则描述 函数不能返回一个指向一个非静态局部变量 2 2 34vararg vararg Variable Number of Arguments 规则描述 禁止函数使用可变量参数 例如 va list 类型和 目的 代码易读性 2 2 35varinit 参数在使用前要初始化 规则描述 所有的变量在使用之前必须初始化 目的 并非所有的编译器都给予相同的默认值 局限 如果是数组 结构 类 只要它们中的一部分初始化 即视为初始化 int a 2 int b 2 6 7 int h a 0 b 0 no violation h a 1 no violation struct int i int j e f e i 0 g e no violation 如果有条件的初始化 认为是初始化违例 int i j k j func if j i 0 k i violation int i j k j func if j i 0 else i 5 k i violation for int i 0 i Y not compliant undefined behaviour 在 if 或 elif 预处理指令的扩展中定义的标记也会导致未定义的行为 应该避免 如 define DEFINED defined if DEFINED X not compliant undefined behaviour 2 3 2 Pointer arithmetic 算术指针 规则描述 算术指针是不允许被使用的 2 3 3 Limitation of the reference complexity 规则描述 对象声明所包含的间接指针不得多于 2 级
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 方案规范


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!