您遵循哪些准则来提高代码的总体质量?许多人对如何编写 C++ 代码有一些规则(据说)可以使犯错误变得更加困难。我见过人 坚持 那个每 if 语句后面跟着一个大括号块 ({...}).

我感兴趣的是其他人遵循哪些准则及其背后的原因。我还对您认为是垃圾但普遍持有的指南感兴趣。有人可以推荐几个吗?

为了让事情顺利进行,我首先要提到一些:

  • 每次之后都要使用牙套 if / else 声明(如上所述)。其背后的基本原理是,判断单个语句实际上是一个语句还是扩展为多个语句的预处理器宏并不总是容易的,因此此代码会中断:
    // top of file:
    #define statement doSomething(); doSomethingElse

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

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

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

现在交给你了。

有帮助吗?

解决方案

我个人最喜欢的一些:

努力编写代码 常量正确. 。您将利用编译器来帮助清除易于修复但有时令人痛苦的错误。你的代码还将讲述你在编写代码时的想法——对于新人或离开后的维护人员来说很有价值。

退出内存管理业务。学习使用智能指针: std::auto_ptr, std::tr1::shared_ptr (或者 boost::shared_ptr) 和 boost::scoped_ptr. 。了解它们之间的区别以及何时使用其中一种与另一种。其他。

您可能会使用标准模板库。阅读 约苏蒂斯书. 。不要在读完有关容器的前几章后就停下来,认为您了解 STL。推动好东西:算法和函数对象。

其他提示

  1. 删除不必要的代码。

就这些。

  • 使用并强制执行通用的编码风格和准则。 理由: 团队或公司中的每个开发人员都能够阅读代码,而不会因不同的大括号样式或类似情况而分心。
  • 定期对整个源库进行完全重建(即进行每日构建或每次签入后构建)并报告任何错误! 理由: 源几乎总是处于可用状态,并且在“实施”后不久就会发现问题,而解决问题的成本很低。

打开编译器中可以出现的所有警告(gcc: -Wall 是一个好的开始,但不包含所有内容,因此请检查文档),并使它们出错,以便您必须修复它们(gcc: -Werror).

其中一个答案中提到的谷歌风格指南非常可靠。虽然里面有一些毫无意义的东西,但好处多于坏处。

萨特和亚历山德雷斯库就这个主题写了一本不错的书,叫做 C++ 编码标准.

以下是小我的一些一般提示:

  1. 你的缩进和括号风格都是错误的。其他人的也是如此。因此请遵循项目的标准。放下你的骄傲并设置你的编辑器,以便一切都尽可能与代码库的其余部分保持一致。不得不阅读缩进不一致的代码真的很烦人。也就是说,括号和缩进与“改善代码”无关。这更多的是提高您与他人合作的能力。

  2. 好好评论一下。这是非常主观的,但总的来说,写评论总是好的 为什么 代码按照它的方式工作,而不是解释它的作用。当然,对于复杂的代码,对于不熟悉算法或代码的程序员来说,了解一下也有好处 什么 它也做得很好。非常欢迎链接到所采用算法的描述。

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

这些都很一般。对于具体的技巧,我无法比 Sutter 和 Alexandrescu 做得更好。

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

if( 12 == var )

不是

if( var == 12 )

因为如果您错过输入“=”,那么它就变成了赋值。在顶级版本中,编译器说这是不可能的,在后者中它运行并且 if 始终为 true。

每当 if 不在同一行时,我都会使用大括号。

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

左大括号和右大括号总是有自己的线条。但这当然是个人惯例。

仅当仅需要解释代码在做什么时才添加注释,而阅读代码无法告诉您相同的信息。

不要注释掉您不再使用的代码。如果您想恢复旧代码,请使用源代码控制系统。注释掉代码只会让事情看起来很混乱,并使实际上重要的注释逐渐消失在注释代码的背景混乱中。

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

还有一个不错的 C++ 风格指南 由 Google 内部使用,其中包括此处提到的大部分规则。

开始写大量注释——但以此为契机重构代码,使其不言自明。

IE:

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()
}
  • 使用选项卡进行凹痕,但是将数据与空格对齐这意味着人们可以通过更改选项卡大小来决定缩进的数量,但也可以保持对齐(例如,当分配值分配值时,您可能希望在垂直线上所有'='结构)

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

  • 切勿在头文件中使用“using”,因为包含该 heafer 的所有内容也会受到影响,即使包含头文件的人不希望在其全局命名空间中包含所有 std(例如)。

  • 如果某些内容超过 80 列,请将其分成多行,例如

    if(SomeVeryLongVaribleName != LongFunction(AnotherVarible, AString) &&
       BigVaribleIsValid(SomeVeryLongVaribleName))
    {
        DoSomething();
    }
    
  • 仅重载运算符以使它们执行用户期望的操作,例如重载 2dVector 的 + 和 - 运算符就可以了

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

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

同样,您可能会在这里找到一些有用的建议: 如何让错误的代码看起来错误?您使用什么模式来避免语义错误?

在可能的情况下,使用前增量而不是后增量。

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

这是 C++ 大师给我的最重要的建议,它在一些关键场合帮助我找到了代码中的错误:

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

有了这两条规则,编译器就会免费告诉你代码中哪里有逻辑缺陷!

另外,对于一些好的技巧,您可以遵循 谷歌博客“厕所测试”.

六个月后看看

确保正确缩进

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

我并不是在为自己寻求建议 - 我正在编写一个静态代码分析工具(当前的商业产品不足以满足我的需求),并且我正在寻找插件的想法来突出可能的功能代码中的错误。

有几个人提到了诸如 const 正确性和使用智能指针之类的事情 - 这就是我可以检查的想法。检查缩进和注释有点困难(无论如何从编程的角度来看)。

智能指针有一种很好的方式来非常清楚地指示所有权。如果您是一个类或函数:

  • 如果你得到一个 原始指针, ,你什么都不拥有。你可以使用被指点者,这是由你的呼叫者提供的,他保证被指点者的寿命比你长。
  • 如果你得到一个 弱指针, ,您不拥有受指点,而且受指点可以随时消失。
  • 如果你得到一个 共享指针, ,您与其他人一起拥有该对象,因此您无需担心。压力较小,但控制也较少。
  • 如果你得到一个 自动指针, ,您是该对象的唯一所有者。这是你的,你是国王。您有权销毁该对象,或将其交给其他人(从而失去所有权)。

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top