您对在方法中声明常量的看法......?

时间:2009-03-24 10:41:04

标签: c++ constants

我正在监督的团队中的开发人员更喜欢在他的测试中将变量声明为常量,例如const int someValue = 1;(而不仅仅是int someValue = 1;)。

当我看到这个时,我发现它有点奇怪,并质疑他做了什么。他的论点是,这对于这个测试来说是明智的 - 因为他所分配的价值永远不会改变。

我一直认为常量应该是在级别声明的。但是,我确实看到了开发人员的观点。

你有什么看法?而且,除了测试之外,你会用常规方法声明常量吗?如果,那么为什么?

14 个答案:

答案 0 :(得分:21)

总的来说,我认为以这种方式明确表达您的意图总是一个好主意,原因如下:

  • 当您编写它时,更容易理解您的意思。
  • 其他人在阅读代码时更容易对代码进行推理。
  • 编译器更容易推断出你想做什么。
  • 编译器更容易防止逻辑错误。

使变量保持不变是完成上述所有操作的完美合法方法,在特定情况下,我希望“我不希望此变量改变其值”。

答案 1 :(得分:11)

来自Scott Meyers的Effective C++(第3章):

  

尽可能使用const

     

关于const的奇妙之处在于它允许您指定语义约束 - 应该修改特定对象 - 并且编译器将强制执行该约束。它允许您与编译器和其他程序员进行通信,使值保持不变。只要这是真的,你应该肯定这样说,因为这样你就可以帮助编制者帮助确保不违反约束条件。

答案 2 :(得分:9)

如果标识符仅在声明的函数中使用,为什么要使用它来规范更广泛的范围。如果分配给标识符的值不应该更改,那么将其标记为编译器以及发现错误都是有用的。

答案 3 :(得分:5)

如果您打算使用静态类型的语言,为什么不去整个九码呢?使用const表示您不希望在第一次分配后该值发生变化。如果你这么做,那就让编译器给你带来麻烦。

出于这个原因,我非常喜欢C ++方法参数中的const关键字......

答案 4 :(得分:3)

这个想法是,如果有特定的原因,你只会留下可变的内容 - 这样可以更容易地推断你的代码。

答案 5 :(得分:3)

当然,需要赋予名称但不需要更改的值应该被称为常量,因为它就是它。

当然,有时常量可以是接口的一部分,和/或需要在更广泛的范围内使用,然后必须在合适的位置声明它。但如果它真的是本地的,那么我发现它并不奇怪。

答案 6 :(得分:3)

如果值的范围是方法(即不在外部使用,但在内部使用了几次),那么它很有意义。特别是,如果使用xml,你可能会使用xml命名空间(仅在一个方法中)多次,但它肯定不是你想要多次维护的东西 - const是理想的。

就C#而言,这也会对闭包产生影响:

const int i = 27;
Func<Foo,bool> predicate = foo => foo.Bar == i;

与:

不同
int i = 27;
Func<Foo,bool> predicate = foo => foo.Bar == i;

第二个必须生成一个捕获类等 - 第一个只是一个静态方法(没有状态),效率更高(每次使用没有堆对象,没有去引用等)。

答案 7 :(得分:3)

许多经验丰富的C ++开发人员实际上认为“const”应该是默认值,并且你必须明确声明某些东西是非const的。当然,只要有意义就使用const。如果某个函数内部的某些内容不能更改,请将其设为const。它没有任何成本,它有助于宣布意图。

答案 8 :(得分:2)

将const声明为const的优点是你不能以一种模糊的方式“意外地”修改它,而代码检查可能会错过。例如,通过引用将其传递给修改其参数的函数。

可论证的缺点是你不能(轻易地)将它传递给代码,该代码采用它实际上没有修改的非const引用。如果你真的相信C ++,这实际上是伪装的一个优势,因为它鼓励你使你的代码的其余部分保持正确。但是如果你必须进行快速更改(例如在调试时),或者你已经发布了API并且无法更改它,那么它看起来就像是一个很好的伪装。

如果函数很短,那么你真的不需要“const”来告诉你是否要通过赋值显式修改局部变量。你可以在你面前看到变量的所有用途。但在现实生活中,功能有时会变长;人们使用非const参考参数,有时甚至是宏;以及您希望尽快阅读和理解代码的地方;然后它可以帮助一点。

当我记得的时候,我倾向于使用它,如果我忘记的话就不会出汗。当我需要从变量中删除const时,我最常使用它。这告诉我,我对该变量的原始概念是错误的,我需要仔细检查没有使用它的表达式实际上依赖于它不会改变。鉴于C ++具有const关键字,如果您要编写依赖于不变的变量的代码,那么您也可以使用编译器。

通常不值得担心编译器优化问题。一个好的编译器(gcc)可以告诉你,如果你不修改变量,并且不对它进行任何引用,那么无论你是否将它标记为const,它都可以应用适当的优化。

答案 9 :(得分:1)

声明变量常量将阻止您意外更改其值。 这也可以导致编译器优化。

答案 10 :(得分:1)

我倾向于声明任何不会改变const / final的值,并鼓励与我合作的团队中的其他人也这样做。通常在Java中,final意味着“只分配一次,只分配一次”,而不是C的const'初始化而不是更改',你可以创建只有非常量值是循环迭代器的方法。

答案 11 :(得分:1)

尽可能在任何地方做到:

  • 使代码易于阅读;
  • 它要求编译器检查您的场合错误:

    void some_class1::doSomething(const some_class2& cs2)
    {
       // code
       cs2 = cs2; // !!! misspelling cs2 instead cs2_
       //
    }
    
  • 它可以帮助您兼容const - 正确的代码;

  • 它有助于封装。

答案 12 :(得分:0)

我以前从未见过它,但它确实有意义。我会让程序员继续按照他已经开发的方式进行。

答案 13 :(得分:0)

对于测试,这显然很棒。至于“常规”代码,您可以从两个方面来看待它。一方面,代码中任何内容的范围应尽可能小。另一方面,你可以说一个常量更可能在一个类中使用,因此应该始终在类级别声明,以防止出现双常量。

我想说,只声明类级别常量,并且只有在有充分理由时才使用方法常量。 一个原因可能是方法的目的是为某些API调用提供抽象,并且您需要一些常量值。在这种情况下,您不希望类级别常量使类的其余部分混乱。