物探论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 4135|回复: 4

[Geosoft] 翻译】geosoft C++ Programming Style Guidelines (已翻译完毕命名部...

[复制链接]
发表于 2013-3-6 20:32:58 | 显示全部楼层 |阅读模式
本帖最后由 天涯 于 2013-3-6 20:40 编辑

1 介绍
  这份文档罗列了C++ 开发社区中基本相同的编程指导。

  指导是基于大量的代码、个人经验、实际需求及其他资料中的建议 [1] - [4]

  使用一份新的指导而不是引用这些资料中主要的原因就是这些这些指导过于宽泛,我们需要更加具体的规则(尤其是命名方面)。同样,整个指导把规则增加了注释,使得在代码审计中要比之前的规则指导易于使用。值得一提的是,编程指导中包含着许许多多方面,这份文档集中在代码规则上,其他可以参考 C++ Programming Practice Guidelines.

     IDE提供了代码隐藏、上色和自动格式化等等功能,但程序员不应该依靠这些特性。源代码不应当局限在当前正在使用的IDE中,而是在写代码时要使他尽量能够在任何类型的IDE下都可以清晰的阅读


1.1 指南的样式
指南以话题的形式组合,并且每个指南都有一个可以用于引用的标号

n. 指南简单描述
可能的例子
原因、背景、附加信息
第三段很重要,代码编写标准通常会引起“圣战” 标注出每种标注的使用背景就很重要了:)

1.2 指南的重要性
在指南里,分为必须、应该和推荐三种等级。

2 通用指南
1. 任何违反本指南但提高代码阅读性的方法都是允许的
指南的主要目的就是增加代码的可读性,提供代码质量。让代码更好的被理解和维护。在这种指南中对于特殊情况的事件是无法包括的,需要程序员灵活的运用。

2.如果个人不喜欢这种方式,可以违背指南
制作这份文档的目的是为了指南,而不是规定一种必需人人遵守的规则。有经验的程序员通常有自己的一种类似于本指南的方法。但有这样一份指南,当需要人来所熟悉、理解它,通常可以使人们考虑编程的方法,评估他们自己在这一领域的习惯。

另一方面来说,对于新程序员和尚缺少经验的程序员们想要更快的进入编程这个行业中,遵循一份代码指南是一条方便、简单的道路

3 命名惯例3.1 常见的命名惯例
3. 命名变量类型时必须用起始字母大写的单词
Line, SavingsAccount
Common practice in the C++ development community.            


4. 变量必须的起始字母小写
line, savingsAccount
Common practice in the C++ development community. 使得变量与类型可以清晰的分辨,也解决了变量与类型名的冲突

Line line


5. 命名常量应当使用全大写字母,单词之间使用下划线连接
MAX_ITERATIONS, COLOR_RED, PI
Common practice in the C++ development community. 通常情况下,常量的使用应该控制在最小限度内,在很多情况下可以把值变为方法:  int getMaxIterations() // NOT: MAX_ITERATIONS = 25  {    return 25;  }
这样既清晰阅读,又确保了这个接口对于类来说值是统一的。


6. 命名函数时一定要使用动词并且起始字母小写。
getName(), computeTotalWidth()
C++社区常用规范。 与命名变量类似,但是C++中的函数可以被它自己的特有的方式识别出来。

7. 命名空间应该使用小写
model::analyzer, io::iomanager, common::math::geometry
C++社区常用规范。

8. 命名模板类型应该使用一个单一的大写字母。
template<class T> ... template<class C, class D> ...
C++社区常用规范。 这样使得模板名称与其他使用的名称清晰的独立出来

9. 简略词必须不使用全大写
exportHtmlSource(); // NOT: exportHTMLSource();

openDvdPlayer(); // NOT: openDVDPlayer();

使用全大写的缩略词会导致冲突,像dVD,hTML这类的同样也不利于阅读,而且当略缩词后面连接了一个单词后,会减少后面单词的可读性。

10. 全局变量应当使用操作符::
::mainWindow.open(), ::applicationContext.getName()
通常应该避免使用全局变量,考虑单间模式的对象来代替。


11. 私有类变量应该使用下划线字尾.
class SomeClass { private: int length_; }
除了变量的名称和类型,作用域是一个变量最重要的属性。 its name and its type, thescopeof a variable is its most important feature. 通过下划线来区分局部变量和类的私有变量是很方便的事情。因为类变量具有比函数变量更大的作用域因此应当值得程序员的注意。
同时还使得当变量出现问题时,更方便的解决。

  void setDepth (int depth)
  {
    depth_ = depth;
  }
这种方案的一个问题就是应当使用下划线做前缀还是后缀,这两种方法都被广泛的应用,但后缀更加值得推荐一下,因为我们觉得这样使得单词看起来更舒服。

值得注意的是变量作用域标识的问题已经有很长时间了,这个指南中这条规则被更多的应用了。


12.  通用的变量名应该与类型名一致
void setTopic(Topic* topic) // NOT: void setTopic(Topic* value) // NOT: void setTopic(Topic* aTopic) // NOT: void setTopic(Topic* t)

void connect(Database* database) // NOT: void connect(Database* db) // NOT: void connect (Database* oracleDB)

通过减少不同变量名等方法来减少代码的复杂度,同样使得通过变量名猜测变量类型变得容易。

如果某些情况下无法满足这条指南,非通用的变量会有一个特殊的角色,那么这些变量可以把角色和类型联合起来:

  Point  startingPoint, centerPoint;
  Name   loginName;


13. 所有名称应该使用英语
fileName; // NOT: filNavn
在国际化开发中,英语是首推语言。

14. 变量的作用域长,使用长变量名,变量作用域短,使用短变量名。
用于短暂存储或序号等的临时变量应该尽量保持简单。一个程序员在读到这些变量就可以推断出变量的值不会在外部使用,而且只是作用于很少行代码。常见的临时变量有:整数:i、j、k、m、n 字符: c、d

15. 对象名是一种暗示,应该避免再次出现在方法中
line.getLength(); // NOT: line.getLineLength();
在类定义时函数看起来似乎正常,但在上例中可以看的很清楚,多余了。


3.2 特定的命名指南
17. 当一个属性被允许修改,那么必须要通过使用get/set函数
employee.getName();

employee.setName(name);

matrix.getElement(2, 4);

matrix.setElement(2, 4, value);

C++社区常用规范。在java中,这已经基本变成了一种标准。

18. 可以使用compute命名需要在函数内进行计算的函数
valueSet->computeAverage();

matrix->computeInverse()

给阅读代码者一个清晰的认识,这里是一个潜在的消耗时间的操作,当需要重复时,就可以考虑缓存函数执行结果。一致的使用这种命名方式可以提高代码的可读性。

19. 可以使用find命名需要在函数内进行查找的函数
vertex.findNearestVertex();

matrix.findMinElement();

给阅读代码者一个清晰的认识,这是一个仅仅为了查找的操作,这种函数使用最少的操作。一致的使用这种命名方式可以提供代码的可读性。

20. initialize 可以用来命名一个对象或强模板的建立。
printer.initializeFontSet();
美式的initialize要比英式的initialise好. 不应该使用略缩词init

21. 代表着可视化组件的变量,应该具有组件类型的后缀名。
mainWindow, propertiesDialog, widthScale, loginText,

leftScrollbar, mainForm, fileMenu, minLabel, exitButton, yesToggle etc.

增加可读性,可以直观的看出变量类型和对象资源。

22. 当表示多个对象时,应该使用复数形式。
vector<Point> points; int values[];
增加可读性,可以直观的看出变量类型和可以应用于此种类型的操作。

23. 当表示多个对象的个数时,应该使用前缀n
nPoints, nLines
在数学界中表示对象数目的方式。

24.当表示一个实体的序号时,应该使用后缀
tableNo, employeeNo
在数学界中表示实体的方式。

一种优雅的替换方式是使用前缀i:iTable, iEmployee。在迭代器中使用。( This effectively makes them named iterators. )


25. 迭代器中的变量应该起名为i、j、k等
for (int i = 0; i < nTables); i++) { : }

for (vector<MyClass>::iterator i = list.begin(); i != list.end(); i++)

   { Element element = *i; ... }

在数学界中表示迭代变量的方式。
变量名为j、k等变量,应该只在紧凑的循环中使用。


26. 前缀is应该在布尔变量或返回布尔值的函数中使用。
isSet, isVisible, isFinished, isFound, isOpen
C++社区通用规范 及 java部分强制需求。
使用is前缀解决了一个常见的布尔变量命名问题,使用stauts、flag通常是比较差的布尔变量名。

有一些替换的变量前缀可能更加使用:has、can和should:

  bool hasLicense();  bool canEvaluate();  bool shouldSort();

27. 互补的名字必须用于互补的操作
get/set, add/remove, create/destroy, start/stop, insert/delete,

increment/decrement,old/new, begin/end, first/last, up/down,

min/max, next/previous, old/new, open/close, show/hide, suspend/resume

通过对称减少复杂性

28. 应该避免缩写
computeAverage(); // NOT: compAvg();
有两类单词,一类是经常会被使用的单词,永远不要缩写他们:
cmd   instead of   command
cp    instead of   copy
pt    instead of   point
comp  instead of   compute
init  instead of   initialize

还有一类是具有特殊含义的短语,基本被所有人所熟知,要使用这种缩写:

HypertextMarkupLanguage  instead of   html
CentralProcessingUnit    instead of   cpu
PriceEarningRatio        instead of   pe


29. 对于指针的特殊命名应该避免
Line* line; // NOT: Line* pLine; // NOT: LIne* linePtr;
在C/C++ 环境中,许多变量都是指针,因此许多约定都无法遵守。同样在C++中对象经常不具有明显的类型,程序员应该避免特殊的实习。只有当一个对象的实际类型特别重要时,变量名才应该着重它的类型。(Many variables in a C/C++ environment are pointers, so a convention like this is almost impossible to follow. Also objects in C++ are often oblique types where the specific implementation should be ignored by the programmer. Only when the actual type of an object is of special significance, the name should emphasize the type. )

30. 必须避免否定的布尔变量名
bool isError; // NOT: isNoError bool

isFound; // NOT: isNotFound

这样做的问题是在逻辑判断中使用了双重否定无法第一时间判断出含义: !isNotFound

31. 枚举常量应具有一个共同的前缀类型名
enum Color { COLOR_RED, COLOR_GREEN, COLOR_BLUE };
这样命名增加了额外信息,哪里可以找到这些变量、哪几种常量是一起的以及代表了什么样的内容。
一种替代方式是保持通过类型进行引用Color::RED, Airline::AIR_FRANCE

注意枚举类型的变量名应该是单数形式enum Color {...}.一个复数的名字尽管看起来没有什么区别,但在使用时看起来非常愚蠢。


32. 异常函数应当具有后缀Exception.
class AccessException { : }
异常函数不应该作为程序的主要设计部分,如此命名使得它远离其他的函数。

33. 函数(方法具有返回值)应当被命名为他们返回的事物,过程(方法返回为空)应该被命名为做了何事。
增加可读性,使得可以清晰的看到这个单元应该怎么用特别是什么不支持。这同样使得它避免了边界效应的影响。
回复

使用道具 举报

发表于 2013-3-10 19:39:13 | 显示全部楼层
不错的帖子
回复 支持 反对

使用道具 举报

发表于 2013-3-24 09:30:21 | 显示全部楼层
学习学习。
回复 支持 反对

使用道具 举报

发表于 2014-3-1 18:07:59 | 显示全部楼层
墨雨知风 发表于 2013-3-10 19:39
不错的帖子

学习学习
回复 支持 反对

使用道具 举报

发表于 2014-10-26 08:57:23 | 显示全部楼层
学习学习,谢谢了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|物探论坛 ( 鄂ICP备12002012号 微信号:iwutan )

GMT+8, 2024-4-20 07:52 , Processed in 0.065775 second(s), 15 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表