C++编码规范
分類: 图书,计算机/网络,程序设计,C C++ C# VC VC++,
作者: 陈世忠 编著
出 版 社: 人民邮电出版社
出版时间: 2002-5-1字数: 323000版次: 1版1次页数: 240印刷时间: 2002/06/01开本:印次:纸张: 胶版纸I S B N : 9787115102867包装: 平装编辑推荐
内容简介
本书由300多条C++编程原则组成,融合并提炼了许多人多年开发C++程序积累下来的成熟经验,意在帮助读者形成良好的编程风格,迅速跨入业已存在的且具有相当高度的技术层次,并期望能够为提高代码的复用性提供积极的参考。 书中对每条原则给出了针对该原则的描述,并辅以实例加以说明,同时阐述了为什么要这么做的道理。每条原则相对独立又前后呼应,不需要花费大块的时间进行系统地阅读,按类细分的原则会让你学起来更轻松。 本书作者所在的部门达到CMM第5级(最高级)标准,书中列举的很多原则被列入该部门必须遵从的标准文档;且本书源于开发、用于开发,针对性比较强。本书适合有一定C++语言基础的人阅读。如果你是一个初学者,希望一开始就养成良好的编程习惯,那么本书也会对你有所帮助。本书还可供软件开发项目组参考。
作者简介
目录
第0章为什么要用C++
0.1原因
0.2语言的发展和代码复用
0.3代码复用的特点
0.4代码复用对我们的影响
第1章命名原则
原则1.1关于类型名
原则1.2关于变量和函数名
原则1.3关于全大写的函数名(建议)
原则1.4关于宏、常量和模板名
原则1.5关于指针标识符名(供参考)
原则1.6关于变量名前缀(供参考)
原则1.7关于匿名命名空间级标识符的前缀
原则1.8减少匿名命名空间级标识符
原则1.9命名时避免使用国际组织占用的格式
原则1.10名字要本着清楚、简单的原则
原则1.11尽量用可发音的名字
原则1.12尽量用英文命名
原则1.13尽量选择通用词汇并贯穿始终
原则1.14避免用模棱两可、晦涩或不标准的缩写
原则1.15避免使用会引起误解的词汇
原则1.16减少名字中的冗余信息
原则1.17建议起名尽量通俗,太专一会限制以后的扩展
原则1.18名字最好尽可能精确地表达其内容
原则1.19避免名字中出现形状混淆的字母或数字
原则1.20命名类和成员使得“object.method()”有意义
原则1.21类和对象名应是名词
原则1.22实现行为的类成员函数名应是动词
原则1.23类的存取和查询成员函数名应是名词或形容词
原则1.24变量名应是名词
原则1.25布尔型的名字要直观
原则1.26关于函数的左值参数和右值参数名
原则1.27避免局部名和外层的名字冲突
原则1.28用a、an、any区分重名(参数)
原则1.29模板类型名应有意义
第2章类型的使用
原则2.1避免隐式声明类型
原则2.2慎用无符号类型
原则2.3少用浮点数除非必须
原则2.4用typedef简化程序中的复杂语法
原则2.5少用union
原则2.6慎用位操作
原则2.7用enum取代(一组相关的)常量
原则2.8使用内置bool类型
原则2.9(尽量)用引用取代指针
第3章函数
原则3.1一定要做到先定义后使用
原则3.2函数原型声明放在一个头文件中
原则3.3函数无参数一定要用void标注
原则3.4对于内置类型参数应传值(除非函数内部要对其修改)
原则3.5对于非内置类型参数应传递引用(首选)或指针
原则3.6关于何时用指针传递参数
原则3.7避免使用参数不确定的函数
原则3.8若不得不使用参数不确定的函数,用,<stdarg.h>提供的方法
原则3.9避免函数的参数过多
原则3.10尽量保持函数只有唯一出口
原则3.11显式定义返回类型
原则3.12(非void)任何情况都要有返回值
原则3.13若函数返回状态,尝试用枚举作类型
原则3.14返回指针类型的函数应该用NULL表示失败
原则3.15函数尽量返回引用(而不是值)
原则3.16若必须返回值,不要强行返回引用
原则3.17当函数返回引用或指针时,用文字描述其有效期
原则3.18禁止成员函数返回成员(可读写)的引用或指针
原则3.19重复使用的代码用函数替代
原则3.20关于虚友元函数
原则3.21关于虚构造函数
第4章类的设计和声明
原则4.1类应是描述一组对象的集合
原则4.2类成员应是私有的(private)
原则4.3保持对象状态信息的持续性
原则4.4提高类内聚合度
原则4.5降低类间的锅合度
原则4.6努力使类的接口少而完备
原则4.7保持类的不同接口在实现原则上的一致性
原则4.8保持不同类的接口在实现原则上的一致性
原则4.9避免为每个类成员提供访问函数
原则4.10不要在类定义时提供成员函数体
原则4.11函数声明(而不是实现)时定义参数的缺省值
原则4.12恰当选择成员函数、全局函数和友元函数
原则4.13防范、杜绝潜在的二义性
原则4.14显式禁止编译器自动生成不需要的函数
原则4.15当遇到错误时对象应该应对有度
原则4.16用嵌套类的方法减少匿名命名空间类的数量
第5章(面向对象的)继承
原则5.1“公共继承(publicinheritance)”意味着“派生类是基类”
原则5.2关于“有”和“由…实现”
原则5.3关于继承和模板(template)的区别
原则5.4关于继承接口和继承实现
原则5.5限制继承的层数
原则5.6继承树上非叶子节点的类应是虚基类
原则5.7显式提供继承和访问修饰:public、protected或private
原则5.8显式指出继承的虚函数
原则5.9基类析构函数(destructor)首选是虚函数
原则5.10绝不要重新定义(继承来的)非虚函数
原则5.11绝不要重新定义缺省参数值
原则5.12不要将基类强制转换成派生类
原则5.13关于C++中的分支用法选择
原则5.14慎用多重继承
原则5.15所有多重继承的基类析构函数都应是虚函数
第6章内存分配和释放
原则6.1用new、delete取代malloc、calloc、realloc和free
原则6.2new、delete和new[]、delete[]要成对使用
原则6.3确保所有new出来的东西适时被delete掉
原则6.4谁申请谁释放
原则6.5当对象消亡时确保指针成员指向的系统堆内存全部被释放
原则6.6自定义类的new/delete操作符一定要符合原操作符的行为规范
原则6.7自定义类的new操作符一定要自定义类的delete操作符
原则6.8当所指的内存被释放后,指针应有一个合理的值
原则6.9记住给字符串结束符申请空间
第7章初始化和清除
原则7.1声明后就初始化强于使用前才初始化
原则7.2初始化要彻底
原则7.3确保每一个构造函数都实现完全的初始化
原则7.4尽量使用初始化列表
原则7.5初始化列表要按成员声明顺序初始化它们
原则7.6构造函数没结束,对象就没有构造出来
原则7.7不要用构造函数初始化静态成员
原则7.8拷贝构造函数和赋值函数尽量用常量参数
原则7.9让赋值函数返回当前对象的引用
原则7.10在赋值函数中防范自己赋值自己
原则7.11拷贝和赋值要确保彻底
原则7.12关于构造函数、析构函数、赋值函数、相等或不等函数的格式
原则7.13为大多数类提供缺省和拷贝构造函数、析构函数、赋值函数、相等
函数
原则7.14只有在有意义时才提供缺省构造函数
原则7.15包含资源管理的类应自定义拷贝构造函数、赋值函数和析构函数
原则7.16拷贝构造函数、赋值函数和析构函数要么全自定义,要么全生成
原则7.17类应有自己合理的拷贝原则:或浅拷贝或深拷贝
原则7.18若编译时会完全初始化,不要给出数组的尺寸
原则7.19将循环索引的初值定在循环点附近
原则7.20确保全局变量在使用前被初始化
第8章常量
原则8.1关于常量修饰符的含义
原则8.2在设计函数原型时,对那些不可能被修改的参数用常量修饰
原则8.3类成员可以转换成常量形式暴露出来
原则8.4关于常量成员函数
原则8.5不要让常量成员函数修改程序的状态
原则8.6不要将常量强制转换成非常量
原则8.7任何变量和成员函数,首选用const修饰
第9章重载
原则9.1仔细区分带缺省值参数的函数和重载函数
原则9.2确保重载函数的所有版本有共同的目的和相似的行为
原则9.3避免重载在指针和整型类型上
原则9.4尽量避免重载在模板类型上
第10章操作符
原则10.1遵守操作符原本的含义,不要创新
原则10.2确保自定义操作符能和其他操作符混合使用
原则10.3区分作为成员函数和作为友元的操作符
原则10.4关于前后缀操作符
原则10.5确保相关的一组操作符行为统一
原则10.6绝不要自定义operator&&()、operatorll()和operator,()
第11章类型转换
原则11.1尽量避免强制类型转换
原则11.2如果不得不做类型转换,尽量用显式方式
原则11.3使用新型的类型转换并确保选择正确
原则11.4用虚函数方式取代dynamic—cast
原则11.5自定义类最好提供显式而不是隐式转换函数
原则11.6用关键字explicit防止单参数构造函数的类型转换功能
原则11.7限制隐式类型转换的类型数
原则11.8避免多个函数提供相同的类型转换
第12章友元
原则12.1少用友元
原则12.2减少拥有友元特权的个数
第13章模板
原则13.1使用模板如果有限制条件一定要在注释和文档中描述清楚
原则13.2模板类型应传引用/指针而不是值
原则13.3注意模板编译的特殊性
原则13.4嵌套template的>>中间要加空格以区别于operator>>
第14章表达式和控制流程
原则14.1让表达式直观
原则14.2避免在表达式中用赋值语句
原则14.3不能将枚举类型进行运算后再赋给枚举变量
原则14.4避免对浮点类型做等于或不等于判断
原则14.5尝试用范围比较代替精确比较
原则14.6范围用包含下限不包含上限方式表示
原则14.7关于goto
原则14.8在循环过程中不要修改循环计数器
第15章宏
原则15.1彻底用常量替代(类似功能的)宏
原则15.2代码中的数值应由一个有意义的标识符代替
原则15.3若宏值多于一项,一定要使用括号
原则15.4不要用分号结束宏定义
原则15.5彻底用inline函数替代(类似功能的)宏函数
原则15.6不好被替代的宏函数
原则15.7函数宏的每个参数都要括起来
原则15.8不带参数的宏函数也要定义成函数形式
原则15.9用()将函数宏的函数体括起来
原则15.10彻底用typedef代替宏定义新类型
原则15.11不要在公共头文件中定义宏
原则15.12不要用宏改写语言
第16章异常(extepttion)处理
原则16.1确保代码在异常出现时能正确处理
原则16.2正确注释代码的异常处理能力
原则16.3减少不必要的异常处理
原则16.4不要利用异常处理机制处理其他功能
原则16.5注意模板类型可能会破坏异常处理的一些约定
原则16.6确保异常发生后资源还能被回收
原则16.7特别当心析构时发生异常
原则16.8抛出的异常最好是一个对象
原则16.9捕捉异常时绝不要先基类后派生类
原则16.10捕捉异常时用引用
第17章代码格式
原则17.1水平缩进每次用两个空格
原则17.2不要在引用操作符前后加空格
原则17.3不要在单目操作符和其操作对象间加空格
原则17.4不要在“::”前后加空格
原则17.5在“,”“;”之后(而不是之前)加空格
原则17.6在关键字和其后的“(”间加一个空格
原则17.7文件中的主要部分用空行分开
原则17.8函数间要用空行分开
原则17.9组局部变量声明和代码之间用空行分开
原则17.10用空行将代码按逻辑片断划分
原则17.11可以考虑将if块和else/elseif块用空行分开
原则17.12函数返回语句要和其他语句用空行分开
原则17.13每一行不超过78个字符
原则17.14当一条语句超过78个字符时按逻辑划分成不同行
原则17.15花括号()要单独占一行
原则17.16花括号中没有或只有一条语句时也不省略花括号
原则17.17不要在一行中放多于一条语句
原则17.18语句switch中的每个case各占一行
原则17.19语句switch中的case按字母顺序排列
原则17.20为所有switch语句提供default分支
原则17.21若某个case不需要break一定要加注释声明
原则17.22变量定义应集中放置、各占一行,并按字母顺序排列
原则17.23定义指针和引用时*和&紧跟类型
原则17.24按编译器解析顺序放置变量声明的修饰符
原则17.25关于函数声明和定义的格式
原则17.26函数名和左括号间不要空格
原则17.27声明函数时给出参数的名字,除非没有用处
原则17.28关于类内不同级别的元素排列顺序
原则17.29关于类成员函数的排列顺序
原则17.30类成员变量按字母顺序排列
原则17.31关于静态成员的访问
原则17.32关于字符常量
原则17.33用带颜色的编辑器
第18章注释
原则18.1用英语写全部的注释
原则18.2确保注释完善你的代码,而不是重复你的代码
原则18.3注释用词要精确,不能有二义性
原则18.4注释中的术语要通用
原则18.5注释要简单、清楚、切中要害
原则18.6注释不能超出被注释代码所包含的内容
原则18.7注释中避免引用容易变化的信息
原则18.8确保所有注释(随代码)及时更新
原则18.9注释不具备约束使用者行为的能力
原则18.10注释不要嵌套
原则18.11不要用/**/注释掉(大块)代码,应该用#if0
原则18.12区分“战略性”注释和“战术性”注释
原则18.13行末注释尽量对齐
原则18.14单独的注释行和被注释语句缩进相同的空格
原则18.15减少不必要的单独占一行的注释
原则18.16对每个#else或#endif给出行末注释
原则18.17对每个引用的头文件给出行末注释
原则18.18对每个空循环体给出确认性注释
原则18.19关于函数注释
原则18.20关于注释频率
第19章文件和目录
原则19.1使用统一而且通用的文件名后缀
原则19.2关于文件名的选择
原则19.3关于文件/目录名的字符集选择
原则19.4关于每个类的文件组成
原则19.5关于模板类的文件安排
原则19.6保持文件前言的简洁性
原则19.7关于文件的段落安排
原则19.8关于目录组织
第20章头文件
原则20.1头文件多次引用的防范
原则20.2确保公共头文件的自足性
原则20.3只引用需要的头文件
原则20.4引用时“”和<>的用法
原则20.5引用头文件的顺序
原则20.6引用时不要用绝对路径
原则20.7将函数库放在一个单独的目录下引用
原则20.8不要在头文件中定义常量/变量
原则20.9任何声明若被多个源文件引用则应在一个头文件中
原则20.10在源文件中不要用关键字extern
第21章条件编译
原则21.1最小化条件编译的使用范围
原则21.2若使用#if或#ifdef,不要遗漏#else
原则21.3编译条件的含义要具体
原则21.4对复杂的编译条件用括号使其清晰
原则21.5条件编译和普通条件语句不要混合使用
原则21.6若只测试某符号是否存在,不要给该符号赋值
第22章编译
原则22.1关注编译时的警告(warning)错误
原则22.2把问题尽量暴露在编译时而不是运行时
原则22.3减少文件的依赖程度
原则22.4减少编译时间
原则22.5透彻研究编译器
第23章兼容性
原则23.1遵守ANSIC和ISOC++国际标准
原则23.2将不符合国际标准的代码与其他代码分开
原则23.3不要假设字符类型是否是有符号类型
原则23.4运算时显式转换有符号和无符号类型
原则23.5注意双字节字符的兼容性
原则23.6恰当使用位操作符
原则23.7注意位域(bitfield)变量的兼容性问题
原则23.8不要强制引用/指针指向尺寸不同的目标
原则23.9确保类型转换不会丢失信息
原则23.10不要假设类型的存储尺寸
原则23.11如果一定要规定类型的存储尺寸
原则23.12不要假设对象(等数据结构)的存储结构
原则23.13注意运算溢出问题
原则23.14不要假设表达式的运算顺序
原则23.15不要假设函数参数的计算顺序
原则23.16不要假设不同源文件中静态或全局变量的初始化顺序
原则23.17不要依赖编译器基于实现、未明确或未定义的功能
原则23.18注意数据文件的兼容性
原则23.19注意引用公共库的兼容性
原则23.20一定不要重新实现标准库函数
原则23.21将所有#include的文件名视为大小写敏感
原则23.22代码中用到的路径只用“广而不要用“/”
原则23.23确保main()函数总是返回一个整型
原则23.24不要依赖pragmas
第24章性能
原则24.1使用性能追踪分析工具
原则24.2不要用移位代替乘除运算
原则24.3如无必要,不要用非int的整型类型
原则24.4不要使用关键字register
原则24.5避免在循环体内部定义对象
原则24.6减少代价很高的对象拷贝
原则24.7减少临时对象
原则24.8注意大尺寸对象数组
原则24.9返回对象(值)的优化
原则24.10前缀++和--的效率更高
原则24.11恰当使用递归
原则24.12恰当地使用inline函数
原则24.13虚函数和虚继承效率会有一点损失
原则24.14如果合理,使用编译器生成的函数
原则24.15如果合理,构造直传类
原则24.16关于缓存(cache)类成员
原则24.17关于标准库的性能
原则24.18关于偷懒
原则24.19关于勤快
原则24.2080—20原则
第25章其他
原则25.1避免产生全局数据对象
原则25.2确保任何定义只发生一次
原则25.3指针操作中用NULL代替0
原则25.4不要把NULL用在指针以外的领域
原则25.5不要弄巧成拙
原则25.6将不再使用的代码删掉
原则25.7运行时不要改变进程的环境变量
原则25.8该用volatile时一定要用
原则25.9不要使用鲜为人知的替换符号
原则25.10关于代码审查(codeinspection/review)规范
附录供参考的源代码
媒体评论