C编码规范Ver01.docx
- 文档编号:5104697
- 上传时间:2022-12-13
- 格式:DOCX
- 页数:9
- 大小:20.82KB
C编码规范Ver01.docx
《C编码规范Ver01.docx》由会员分享,可在线阅读,更多相关《C编码规范Ver01.docx(9页珍藏版)》请在冰豆网上搜索。
C编码规范Ver01
C++编码规范(Ver0.1)
文档历史
修订日期
修订内容
修订版本
修订人
2006-7-4
初始版
.10
EVA
2006-7-12
STLPORT,跨dll编程,assert
.11
PUZZY
2006-7-19
STLPORT5更新
.12
PUZZY
STLPORT5更新
STLPORT5支持vc71和vc8。
新项目建议使用vc8(vc2005)。
需要的头文件和LIB放在122/horizon/STLPORT5.0.2/目录下。
StlPort与BoundChecker兼容
当BoundChecker与STLPORT一起使用时,会因为stlport使用vector内存池,以及replacementnew,而误报内存泄露等错误。
解决方法:
1,当使用BoundChecker时,把系统目录设置成VC自带的stl目录。
2,当需要stlport与BoundChecker一起使用时,需要改变STLPORT配置后,重新编译stlport。
步骤:
A,修改stlport/stl/_config.h,在39行左右(最前面)加上”#define_STLP_DONT_USE_SHORT_STRING_OPTIM1”
B,修改_site_config.h,在123行左右,“#define_STLP_USE_NEWALLOC1”和“#define_STLP_USE_MALLOC1”
这样编译后的版本,无法使用stlport对string的优化,以及自己的malloc和new。
意义没有方法1大
STLPORT使用规范
1,综述
STLPORT具有对所有容器进行越界检查,遍历器归属,有效性,算法条件检查等各种安全检查。
所以H3D工程使用STLPORT作为标准库。
STLPORT在vc2003/05中,需要使用自己的stream静态链接库。
*.lib已提供。
2,使用
在vc-tools->options->project->VC++directories->,把STLPORT的include,lib目录,分别设置在VC系统include和lib目录的前面。
3,配置
需要打开STLPORTDEBUG功能时,在项目属性->C/C++->PreProcessor->PreprocessorDefinitions->增加_STLP_DEBUG.
跨DLL编程事项
1,不得提供带有stl参数的接口函数
2,不得同时在两个DLL对一个局部HEAP进行操作,例如:
在一个DLL里new的指针,在另外一个DLL内delete
ASSERT定义
使用:
assert_custom(boolb){if(b==false)__asm{int3};}重新定义assert
内存检测
必须使用memorymanager对内存进行检测。
严格控制new以及生命对象周期。
书写new的同时,必须先构造好delete的函数。
在所有出现new和delete的地方,加入memorymanager头文件。
STLPORT和MEMORYMANAGER放在192.168.0.122/share/Horizon
普适原则
1. 直白式的代码比起注释来的更有意义
2. Coders不能为了图方便而牺牲了代码的健壮性和可理解性
3. 格式化规则应当明白直接,花时间考虑如何格式化代码比多花时间编码更有用
4. 规则应该防范那些会引发微妙错误的代码
5. 应该避免无意义的过于烦琐的规则
1. 文件及预处理器
1.1 需要有统一的格式来进行文件头的编写,法律以及更改日志在版本没有稳定前只需留出位置不需要填写内容。
具体统一格式下一版中出。
1.2 在头文件中使用#include guards防止被include多次.
(就是#ifndef xxx_hpp #define xxx_hpp #endif)。
如何使用guards(#if!
definedvs#ifndef)下一版给出。
1.3 Cpp源程序应该最开始#include的头文件必须是其对应的头文件,如果无法编译应该改变其对应的头文件。
1.4 #include一律出现在文件开头, 如果是头文件放在#include guards 之后的开头
1.5 尽量避免头文件依赖,如果某个头文件中需要用到某个类的引用或指针,那么只需要一个forward declaration就足够了。
如:
classRenderer;
Renderer*a;
Renderer&b;
在使用模块时,为了避免过于繁琐的指定所需要的模块中的头文件,可以使用由模块提供的一个功能头文件,这个头文件将包含模块定义的所有头文件。
这个头文件由模块编写者提供。
1.6 使用相对#include路径. 目录结构最好和工程的namespace结构类似
推荐
避免定义预处理的宏 特别是在头文件中(规则1.2例外),请使用enum,const,function,template 等避免宏的定义.
如:
用enum{MusicNum=12}或constintMusicNum=12而不是#defineMusicNum12
用inlinemax(inta,intb){…}或template
2 命名
2.1 类成员变量要使用比较能够明确表意的名字,局部变量名可以简略。
类成员变量与局部变量名在命名上要有区别。
如(非要求),类成员变量为m_hit_count;局部变量名hc
2.2具有改变状态的函数, 应当是E文中的动词短语
2.3 在命名中避免trademark,如h3d,kart_
2.4 短名字应当依照通用惯例. 如i j k用于循环控制变量,p q用于指针和遍历子
2.5 预处理宏应尽量避免 无法避免的时候,它的命名应当是全大写形式,头文件中使用的宏要么就取一个奇长无比的名字,要么就在使用以后#undef掉(避免名字污染)
推荐
选择表示目的的名字 而不是表示实现的名字,比如定义一个已知设备列表
使用list
布尔变量和布尔函数应当是E文中的谓词短语 这样条件语句读起来就好像是E文中的条件句了. 如if (buffer->is_empty())
描述对象状态的函数应当是名词短语 如得到container长度的函数应叫size()而不是get_size()
尽量不使用带有双下划线'__',或是以单下滑线'_'开头的名字
3空格及空行
3.1 单目前缀运算符不能紧跟有空格 如*p,!
is_right;单目后缀运算符不能有前导空格 如f(),a[],i++;->前后都不能有空格
3.2 对于空格与空行,不同人的风格差异很大,不做特别细致的要求;但要求每个单一文件中使用的空格和空行风格必须相同。
3.3 对于组合的位运算,写全括号
if(a&0x01)//ok
if(a&0x01&&b)//bad
if((a&0x01)&&b)//server
3.4 如果表达式要分开多行,请在某个运算符之前分行 这样下一行很明显能看出是上一行的继续
如int b = a
+ 2;
4缩进
4.1 对于缩进,不同人的风格差异很大,不做特别细致的要求;但要求每个单一文件中使用的缩进风格必须相同
5.块和语句的格式化
5.1 '{'和'}'单独占用一行
5.2 '{'和'}'应和该块代码的前一行代码具有相同的缩进
5.3 附属的流程控制子语句使用单独的行
不要这样写 if(...) do_something;
5.4 多行的附属子语句前后必须加'{'和'}'
如
if(...)
{
// one line
// another
}
推荐
如果if子句加了'{''}',else字句也要加,反过来也一样
6. 声明和初始化
6.1 指针和引用一行只能声明一个名字
int*a;//ok
int&b…//ok
floatx,y,z;//ok
inta,*b,&c;//bad
6.2 将*,&和类型名放在一起, 不要和对象名放在一起(如写成int* p, 而不是int *p)
6.3 尽可能晚的定义局部变量,并赋初值
6.4 复用一个变量时不要出于不同的目的. 复用变量并不会节约资源,编译器知道一个变量什么时候没有用了. 相反复用变量会把读代码的人搞糊涂.
推荐
尽可能的使用const. 看的人清楚,用的人也明白,使用错误时编译器还能报错
7.注释
7.1 长注释应和代码分在不同的行
7.2 函数的注释放在一处, 不用在声明和定义两边都写
7.3 对于每一个虚函数, 在还没有被继承的地方注释 注释包括该函数会在何时被调用, 如何被调用, 什么时候会需要重载它. 对于非纯虚函数, 写出它缺省实现的效果
7.4使用标准的C++术语,如类成员函数,而不是方法,是类成员变量,而不是属性。
推荐
注释所有的public和protected成员函数的声明. 那些具有特定意义的函数如拷贝构造函数, 拷贝赋值运算符,析构函数就不用了
所有其它函数(private的非虚函数, 在无名namespace中定义的函数)应该在定义的地 方写下它的注释. 这是为了避免在头文件中留下实现细节的描述
8. 类的组织
8.1在继承类里也重复写virtual关键字, 让别人清楚知道函数的类型
9. 继承和运行时多态
10. 组件文档
10.1 在每一个组件之前使用一段注释描述它的界面 (组件是一个,或是一组具有相 关功能的类和函数的集合, 通常存在于一个头文件中)
10.2 注释的内容应该是描述该组件是什么, 应该如何使用该组件
10.3 为继承类的实现者在共有接口部分写好详细的文档. (避免错误的继承)
10.4 模版的注释文档应当列出在模版(类/函数)的实现中用到了模版参数的那些操作.
10.5 实现细节文档应该与共有接口注释和继承接口注释分开, 最好不要放在头文件中, 并包含一个简练,完整的class invariants(类的不变式)的列表
11. 错误处理和健壮性
推荐
使用assert()(或是适当的代替品)来检测是否有未满足的precondition (前提)和编程错误. 前提是函数执行前必须为真的一个条件.
12. 名字空间 Namespaces
推荐
将你所有的代码放入名字空间中
每一个子模块都应成为一个单独的子名字空间
当访问别的名字空间的名字时, 最好使用显示限定(而不是在使用前加using)
避免使用using指示符
避免导入标准C头文件
将只用于该文件的名字放入无名名字空间(namspace {...}), 这样就不会和其它源文件中的名字冲突
13. 重载 Overloading
13.1 不同的重载函数应当具有相同的语意
13.2 运算符重载应当符合既定习惯
13.3 避免重载虚函数
推荐
为保证常量正确性添加重载函数 当函数返回它的某个参数的non-const reference 或iterator(或*this)的时候, 应当有相应的一个函数返回const reference或 iterator
如:
constRender*getRender()const;
Render*getRender();
14. 类型转换
14.1 了解那种转换更加安全. dynamic_cast<>比static_cast<>安全, static_cast<>和 const_cast<>和reinterpret_cast<>比C风格的转换都要安全
推荐
尽量不使用隐式类型转换
15. 杂项 Miscellaneous
15.1 尽量使用标准库
推荐
不要使用接受可变参数个数的函数(like printf), 因为它们不是类型安全的
类的成员变量尽量不要使用引用类型
classA
{
int&m_t;//bad
public:
A(int&r):
m_t(r)//bad
{}
};
实际工程中必须要注意的地方
内存的分配与释放,必须在同一个dll/exe中进行
不要进行标准库容器(包括string)的传递
再做操作时要先判断或断言操作的参数是否合法
erase(pos)//assert(pos!
=end())
vector[idx]//assert(idx
尽量避免魔数(MAGICNUM)
特别审视数组越界以及标准库的使用方法
intA[12];A[12]=0;//bad
BufferL;//删除容器中若干符合条件的元素
FOR(itrpos=l.begin();pos!
=l.end();)
{
If(…)
{
Itrtp=pos++;
l.erase(tp);
}
else
{
++pos;
}
}
dll尽量使用dll形式的运行时环境
配对使用new,delete--new[],delete[]--malloc,free--fopen,fclose
待议:
Intvs.unsignedint//如何使用
7.15 使用'#if 0...#endif'或'//'注释代码,不要使用'/*...*/'
(我想是因为/**/不支持嵌套注释吧, 而#if 0...#endif可以嵌套)
.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编码 规范 Ver01