您如何成为const正确性转换的?[关闭]


25

经过15年的C ++工作,我仍然没有学会使用const。我知道它的用法,但实际上我从来没有遇到过const正确会避免我面临的问题的情况。

那么,您是如何爱上const的好处的呢?


3
我认为const正确性比解决if构造函数或sizeof运算符之类的工具更是正确的。
legends2k 2010年

9
“ const在C ++中起作用的原因是,您可以将其丢弃。如果无法将其丢弃,那么您的世界将会糟透了。” -安德斯·海斯伯格
梅森·惠勒2010年

1
const也是C类型的修饰符,自从第一个ANSI C标准以来一直存在。
Huperniketes

被Java / C#宠坏了,我是一个偏执狂,喜欢离开,断言我有任何机会。可能出错的地方将会出错。如果有编译时或运行时帮助,那就算我了!我一听到它3到4次便成为了一名转换者,并跟随了该链接的一部分(足够了解语法,我不需要阅读原因):可能性.com / Cpp / const.html只是因为还没有什么东西出现在我的脸上... ...花费很少的精力就可以正确地纠正它,并且也不会造成伤害。看看Joel的想法:joelonsoftware.com/articles/Wrong.html
工作

Answers:


28

好吧,直到我尝试接受这种哲学时,我才被说服。

我首先开始 const,我将最基本的类成员和成员函数参数中的真正只读成员。

从那里,我无法编译了。然后,我坚持使用这些基本类输入代码,看看以前是否const添加的内容与我对它们的使用相比是否真的合法。当我在代码的其他部分添加常量时,它帮助我修复了一些错误。

它具有传染性。大多数代码具有更高的一致性,而且我发现调试起来更容易,因为它使您确信,如果您开始修改不应修改的内容,编译器将阻止您。

一旦我使应用程序再次运行,它就会变得更快(必须更改一些我发现不适合该工作的算法),错误更少,阅读代码时更容易理解。

我被说服了。

现在,我认为当您除了使用constness之外还使用许多断言时,它会更好,因为它使您在必须编写新代码或修改当前代码时充满信心。您知道编译器会在必要时阻止您。它使您忘记必须检查所有不应该修改的内容,然后您有更多的思考时间来进行更多针对业务的思考或体系结构思考。


8
+1为传染性,这实际上意味着您必须成为const转换或完全避免使用它。
马丁·威克曼

您还不必依赖于没有进行const正确性处理的库。当您的方法意味着您不能调用任何gui函数(因为它们不是const)而无法使用时,您的方法将不起作用-或者您需要在每次gui调用中将其抛弃。
马丁·贝克特

4
+1表示“发现它更容易调试”,我const什至甚至对我知道不需要更改的局部变量也使用这种方式,这样,在阅读代码时,我可以略过a if或a for或其他形式:我的变量是常量,我知道它不会改变!我不太在乎优化,但是我的大脑有限,缩进+ const-correctness的帮助很少!
Matthieu M.

@MatthieuM .:是否曾经考虑过改用Haskell?;-)
乔治

@乔治:我已经探索了它,甚至购买了“真实世界Haskell”。老实说,默认情况下,我对懒惰和涌现出的许多神秘运算符不感到兴奋。
Matthieu M.

15

我从来都不是面向对象编程的拥护者,而且如果我成长得越来越少,那么我通常对编程的了解也会更多。当我研究了不同的编程范例时,我意识到不变性是程序设计核心概念之一,它会影响根据任何形式编写的软件原理。它在函数式编程中非常重要,除了简单的安全保证之外,还涉及优化和并发性。

基本上,所有可能不可变的事物都应该是不变的,除非您有充分的理由说明可变状态。以我的经验,用任何语言编写程序以实现此目标都可以产生更安全,更好的代码。const只要适用,您就不会失去任何东西-不变性是免费的!

(顺便说一句,我很想为C ++的方言创建一个GCC分支的想法,const除非所有类型明确地限定为C ++ mutable。如果有这种支持,我将全力以赴维护和使用它。)


从OO的角度来看,不变性通过防止不受限制的写访问来强制执行封装。它减少了类之间的耦合,因为不可变对象必须完全管理其自身的状态,因此其行为类似于普通值。常量正确性极大地简化了证明程序正确性的过程,尤其是在并发编程的情况下。使用C ++引用和C ++ 0x右值引用语义,您可以使用不可变的对象,而不必担心在各处复制它们的开销。此外,如果您使用的是大多数不可变的对象,则编译器可以发挥一些非常神奇的优化魔术作用。

我知道它const到处都是打字的麻烦,但是您很快就会习惯它,并且随着时间的流逝,就可靠性和可维护性而言,好处显而易见。我不是一个出色的作家,要证明这一点似乎是一项艰巨的任务,但是我知道const正确性对我作为开发人员在设计和实现程序时有极大的帮助,我认为经验是在这方面最好的老师。


2
您基本上只是说const正确性是一件好事。您说它“导致更安全,更好的代码”。你能说为什么吗?
David Reis 2010年

我完全处于不变性阵营中,我最喜欢的语言是Erlang。但是我认为在C ++中通过const进行不变性并不是真正免费的。有一些缺点,例如可读性差的代码,相同方法的const和非const版本,或者将const抛弃会导致“没有其他选择”。
grok 2010年

1
我建议您不要仅仅使用mutable,因为它在const正确性方面具有明确的含义。这意味着该数据对象可以以不影响对象行为的方式进行更改,并允许诸如缓存答案之类的事情。组成另一个关键字。
David Thornley 2010年

2
@David Thornley:出于一致性考虑,这mutable是合乎逻辑的选择。void alter(mutable Point&)就像mutable int foo对局部变量一样有意义,并且这些都不会与现有语言或的现有用法发生冲突mutable。另外,Object mutable* mutable看起来还很吓人,可以警告它是否必要或正确。
乔恩·普迪

如果您曾经做过叉子,请考虑改用CLang-会减轻痛苦。
gf 2010年

6

const正确性的优点在于,它在程序上施加了约束,并使得对程序的各个部分进行推理变得容易。

纪律是您需要知道某些地方可能会更改。相应的优点是,当您可以知道可能会更改状态的代码时,更容易看到一段代码。


1
“必须编写程序供人们阅读,并且只能偶然地使机器执行。” -Abelson&Sussman,SICP
布兰登·

4

保持常量正确强调了设计的正确性,我将其视为不使用强制转换运算符的类似问题;因此,不要使用强制转换并保持const正确,最小化可变的用法-所有这些都是衡量设计水平的指针,而不是解决现有总体问题的实际工具。

PS:const一旦我理解了使用的正确性,我就完全相信了;)



2

我看到编写const正确代码的两个主要原因。一种是编译器是您的朋友,通过使用const可以警告您潜在的错误。第二个原因是const正确性使代码更具可读性。例如,您始终知道哪些函数参数是输入,哪些是输出。您还知道哪些成员函数会修改对象,而哪些不会。您无需立即阅读代码即可立即了解这些内容。当然,这假定对的使用非常明智const_cast


2

我一知道自己是有可能的,就当了convert依者。从“良好的编程风格”的角度来看,这对我来说很有意义。有很多原因可以使const正确是一种好习惯:

  • 可读性和理解性。如果我正在阅读其他人的代码,并且函数将const引用用作参数,则我知道该参数仅用作只读变量。这是一个巨大的胜利,尤其是在代码是多线程环境的情况下。
  • 编译器可以利用const限定符来辅助其优化过程。
  • 假设在我不希望更改的情况下,我有一个A类对象。然后,只能为该对象调用的成员函数是const。

2

总结其他答案中涵盖的两点,并添加一个新的答案:

  • const将代码记录给您的API用户。它在函数与其调用者之间形成契约,即该函数不会修改其参数。(请注意,该const_cast功能不能使函数更改其参数,它允许将该参数传递给其他不修改其参数但忘记了const注释的函数。)在函数/循环/等内部也很有用,因为它有助于理解很多内容。与循环不变的方式相同。

  • const向编译器记录您的意图。在编译时发现错误总是比等待代码运行好。

  • const类型安全多态性必需的。指针(所有形式,而不仅仅是原始指针)只有在它们是协变的情况下const(注意:与“ const指针”不同)。协方差需要一个只读接口,而协方差需要一个只写接口。

我首先学习了其中的第二个。我const仅从指针和引用参数的目标开始,直到我开始看到更早捕获错误并开始在局部变量上使用它的好处。

然后我了解到,大多数#defines可以被全局常量替换(在C ++中),并具有类型安全的附加优点。所以我在那里也使用了它。

最终,我参加了有关类型系统和lambda演算的课程,并了解到const和非const类型在本质上是不同的(因为它们支持不同的操作),从那时起,我什至从未考虑过在不大量使用C的情况下编写C ++代码const


1

这是我没看到别人提到的5美分。传递变量时,除非确实需要,否则您不希望按值传递值,以避免额外的构造,破坏和复制。因此,除非您确实必须按值传递值,否则在各处都使用引用,即使您不打算更改传递的值也可以显着提高性能。出于这个原因,当您拥有引用其所有参数的函数时,需要让调用者知道该函数将不会被修改的内容。

它的原理相同,但是我只想添加使用const的实际原因。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.