改进代码的指南

时间:2008-09-13 16:30:51

标签: c++ coding-style

您为提高代码的一般质量遵循了哪些指导原则?很多人都有关于如何编写C ++代码的规则,这些代码可能会使错误变得更加困难。我看到人们坚持每个if语句后跟一个大括号块({...})。

我对其他人遵循的指导方针及其背后的原因感兴趣。我也对您认为是垃圾的指导方针感兴趣,但通常都是这样。任何人都可以提出一些建议吗?

为了让球滚动,我将提到一些开头:

  • 在每个if / else语句(上文提到)之后始终使用大括号。这背后的基本原理是,判断单个语句实际上是一个语句还是扩展为多个语句的预处理器宏并不总是很容易,因此这段代码会破坏:
    // top of file:
    #define statement doSomething(); doSomethingElse

    // in implementation:
    if (somecondition)
        doSomething();

但如果您使用大括号,那么它将按预期工作。

  • 仅使用预处理器宏进行条件编译。预处理器宏可能导致各种地狱,因为它们不允许C ++作用域规则。由于预处理器宏在头文件中具有通用名称,因此我多次搁浅。如果你不小心,你可能会造成各种各样的破坏!

现在告诉你。

21 个答案:

答案 0 :(得分:9)

我个人最喜欢的一些:

努力编写const correct的代码。您将使用编译器来帮助清除容易修复但有时很痛苦的错误。你的代码也将讲述你写作时的想法 - 一旦你离开,对新手或维护者都有价值。

退出内存管理业务。学习使用智能指针:std::auto_ptrstd::tr1::shared_ptr(或boost::shared_ptr)和boost::scoped_ptr。了解它们之间的差异以及何时使用一个与另一个之间的差异。

您可能会使用标准模板库。阅读Josuttis book。不要只是在容器上的前几章之后停下来认为你知道STL。推进到好东西:算法和函数对象。

答案 1 :(得分:9)

  1. 删除不必要的代码。
  2. 就是这样。

答案 2 :(得分:7)

  • 使用并执行通用的编码风格和指南。 基本原理:团队或公司中的每个开发人员都能够阅读代码而不会因为不同的支撑类型或类似情况而分心。
  • 定期对您的整个源代码库进行完全重建(即每次签入后进行每日构建或构建)并报告任何错误! 原理:源几乎总是处于可用状态,并且在“实施”之后不久就会检测到问题,解决问题很便宜。

答案 3 :(得分:7)

打开编译器中可以看到的所有警告(gcc:-Wall是一个良好的开端,但不包括所有内容,请检查文档),并将它们设置为错误,以便您必须修复它们(gcc :-Werror)。

答案 4 :(得分:5)

谷歌的风格指南,在其中一个答案中提到,非常可靠。其中有一些毫无意义的东西,但它比坏的更好。

Sutter和Alexandrescu写了一本关于这个主题的好书,名为 C ++编码标准

以下是lil'ole me的一些一般提示:

  1. 您的缩进和包围样式都是错误的。其他人也是如此。因此,请遵循项目的标准。吞下你的骄傲并设置你的编辑器,以便一切尽可能与代码库的其余部分保持一致。读取不一致的代码真的很烦人。也就是说,包围和缩进与“改进代码”没有任何关系。它更多的是提高你与他人合作的能力。

  2. 评论很好。这是非常主观的,但总的来说,编写关于为什么代码按照它的方式工作的注释总是好的,而不是解释它的作用。当然,对于复杂的代码,对于可能不熟悉算法或代码的程序员来说,也可以了解它正在做什么。非常欢迎使用所用算法描述的链接。

  3. 以尽可能简单的方式表达逻辑。我认为,具有讽刺意味的建议,例如“将常数放在比较的左侧”这里出现了问题。它们非常受欢迎,但对于说英语的人来说,它们往往会破坏程序的逻辑流程。如果你不能相信自己(或你的编译器)正确地写出相等比较,那么一定要使用这样的技巧。但是当你这样做时,你会牺牲清晰度。同样属于这一类的是......“我的逻辑是否有3级缩进?它可以更简单吗?”并将类似的代码滚动到函数中。甚至可能拆分功能。编写优雅地表达底层逻辑的代码需要经验,但值得一试。

  4. 那些非常普遍。对于具体的提示,我不能比Sutter和Alexandrescu做得好得多。

答案 5 :(得分:4)

在if语句中将常量放在左边,即

if( 12 == var )

if( var == 12 )

因为如果你错过了输入'=',它就会变成作业。在顶级版本中,编译器说这是不可能的,在后者运行时,if始终为true。

只要它们不在同一条线上,我就会使用大括号。

if( a == b ) something();
if( b == d )
{
    bigLongStringOfStuffThatWontFitOnASingleLineNeatly();
}

打开和关闭大括号总是得到自己的行。但这当然是个人惯例。

答案 6 :(得分:4)

仅在需要解释代码正在执行的操作时才进行注释,阅读代码时无法告诉您相同的内容。

不要注释掉您不再使用的代码。如果要恢复旧代码,请使用源代码管理系统。注释掉代码只会让事情看起来很混乱,并使你的评论真正重要地消失在评论代码的背景中。

答案 7 :(得分:3)

  1. 使用一致的格式。
  2. 在处理遗留代码时,请使用现有的格式样式,尤其是大括号。
  3. 获取Scott Meyer的书“Effective C ++”
  4. 的副本
  5. 获取Steve MConnell的书Code Complete的副本。

答案 8 :(得分:3)

Google内部使用了一个不错的C++ Style Guide,其中包含了此处提到的大多数规则。

答案 9 :(得分:2)

开始写很多评论 - 但是把它作为重构代码的机会,以便它自我解释。

即:

for(int i=0; i<=arr.length; i++) {
  arr[i].conf() //confirm that every username doesn't contain invalid characters
}

应该更像是

for(int i=0; i<=activeusers.length; i++) {
  activeusers[i].UsernameStripInvalidChars()
}

答案 10 :(得分:1)

六个月后再看看它

答案 11 :(得分:1)

在类似的情况下,您可以在此处找到一些有用的建议:How do you make wrong code look wrong? What patterns do you use to avoid semantic errors?

答案 12 :(得分:1)

此外,对于一些好的技巧,您可以关注Google's blog "Testing on the Toilet"

答案 13 :(得分:1)

以下是C ++专家给出的最重要的建议,它帮助我在几个关键时刻找到了我的代码中的错误:

  • 当方法不应该时使用const方法来修改对象。
  • 当对象不应该来修改对象时,在参数中使用const引用和指针。

使用这两条规则,编译器会告诉您免费在代码中逻辑存在缺陷的地方!

答案 14 :(得分:1)

我在我的C ++项目中使用PC-Lint,特别是它如何引用现有的出版物,如MISRA指南或Scott Meyers的“Effective C ++”和“More Effective C ++”。即使您计划为静态分析工具检查的每个规则编写非常详细的理由,也应该指向您的用户信任的已建立的出版物。

答案 15 :(得分:1)

尽可能使用预增量而不是后增量。

答案 16 :(得分:1)

  1. 设置编码约定并让每个人都遵循约定(您不希望阅读需要您找出下一个语句/表达式的代码,因为它没有正确缩进)
  2. 不断重构您的代码(获取Refactoring的副本,Martin Fowler,书中详细介绍了优缺点)
  3. 编写松散耦合的代码(避免通过编写自解释代码来编写注释,松散耦合的代码往往更容易管理/适应变化)
  4. 如果可能的话,对你的代码进行单元测试(如果你足够大,那就是TDD。)
  5. 提前发布,经常发布
  6. 避免过早优化(分析有助于优化)

答案 17 :(得分:1)

  • 使用标签进行缩进,但将数据与空格对齐 这意味着人们可以通过更改选项卡大小来决定缩进多少,但也可以保持对齐(例如,在为结构赋值时,您可能希望在垂直线中显示所有'=')

  • 总是使用常量或内联函数而不是可能的宏

  • 永远不要在头文件中使用'using',因为包含该heafer的所有内容也会受到影响,即使包含您的标头的人不想在其全局命名空间中使用所有std(例如)。 / p>

  • 如果某些东西长于约80个,请将其分成多行,例如

    if(SomeVeryLongVaribleName != LongFunction(AnotherVarible, AString) &&
       BigVaribleIsValid(SomeVeryLongVaribleName))
    {
        DoSomething();
    }
    
  • 只有重载运算符才能使它们达到用户期望的效果,例如为2dVector重载+和 - 运算符就可以了

  • 总是注释你的代码,即使它只是说下一个块正在做什么(例如“删除这个级别不需要的所有纹理”)。有些人可能需要稍后使用它,在你离开之后,他们不想找到1000行的代码,没有任何评论来表明做什么。

答案 18 :(得分:0)

嗯 - 我可能应该更具体一点。

我不是在为自己寻找建议 - 我正在编写一个静态代码分析工具(当前的商业产品对我想要的东西不够好),我正在寻找插件的想法突出显示代码中可能存在的错误。

有些人提到过const正确性和使用智能指针之类的东西 - 这就是我可以检查的那种想法。检查缩进和注释有点难度(无论如何从编程的角度来看)。

答案 19 :(得分:0)

确保缩进

答案 20 :(得分:0)

智能指针有一种非常清楚地表明所有权的好方法。如果你是一个班级或职能部门:

  • 如果你得到原始指针,你就没有任何东西。你被允许使用指针,由你的来电者提供,他们保证指针对象的存活时间比你长。
  • 如果你得到 weak_ptr ,你就不拥有指针,最重要的是,指针可以随时消失。
  • 如果您获得 shared_ptr ,则您将该对象与其他人一起拥有,因此您无需担心。减轻压力,但也减少控制。
  • 如果您获得 auto_ptr ,则您是该对象的唯一所有者。这是你的,你是国王。你有能力摧毁那个物体,或者把它交给别人(从而失去所有权)。

我发现auto_ptr的情况特别强烈:在设计中,如果我看到auto_ptr,我立即知道该对象将从系统的一个部分“漫游”到另一个部分。

这至少是我在宠物项目中使用的逻辑。我不确定这个主题可以有多少变化,但是直到现在这个规则集对我有用。