经过15年的C ++工作,我仍然没有学会使用const。我知道它的用法,但实际上我从来没有遇到过const正确会避免我面临的问题的情况。
那么,您是如何爱上const的好处的呢?
经过15年的C ++工作,我仍然没有学会使用const。我知道它的用法,但实际上我从来没有遇到过const正确会避免我面临的问题的情况。
那么,您是如何爱上const的好处的呢?
Answers:
好吧,直到我尝试接受这种哲学时,我才被说服。
我首先开始 const
,我将最基本的类成员和成员函数参数中的真正只读成员。
从那里,我无法编译了。然后,我坚持使用这些基本类输入代码,看看以前是否const
添加的内容与我对它们的使用相比是否真的合法。当我在代码的其他部分添加常量时,它帮助我修复了一些错误。
它具有传染性。大多数代码具有更高的一致性,而且我发现调试起来更容易,因为它使您确信,如果您开始修改不应修改的内容,编译器将阻止您。
一旦我使应用程序再次运行,它就会变得更快(必须更改一些我发现不适合该工作的算法),错误更少,阅读代码时更容易理解。
我被说服了。
现在,我认为当您除了使用constness之外还使用许多断言时,它会更好,因为它使您在必须编写新代码或修改当前代码时充满信心。您知道编译器会在必要时阻止您。它使您忘记必须检查所有不应该修改的内容,然后您有更多的思考时间来进行更多针对业务的思考或体系结构思考。
const
什至甚至对我知道不需要更改的局部变量也使用这种方式,这样,在阅读代码时,我可以略过a if
或a for
或其他形式:我的变量是常量,我知道它不会改变!我不太在乎优化,但是我的大脑有限,缩进+ const-correctness的帮助很少!
我从来都不是面向对象编程的拥护者,而且如果我成长得越来越少,那么我通常对编程的了解也会更多。当我研究了不同的编程范例时,我意识到不变性是程序设计的核心概念之一,它会影响根据任何形式编写的软件原理。它在函数式编程中非常重要,除了简单的安全保证之外,还涉及优化和并发性。
基本上,所有可能不可变的事物都应该是不变的,除非您有充分的理由说明可变状态。以我的经验,用任何语言编写程序以实现此目标都可以产生更安全,更好的代码。const
只要适用,您就不会失去任何东西-不变性是免费的!
(顺便说一句,我很想为C ++的方言创建一个GCC分支的想法,const
除非所有类型明确地限定为C ++ mutable
。如果有这种支持,我将全力以赴维护和使用它。)
从OO的角度来看,不变性通过防止不受限制的写访问来强制执行封装。它减少了类之间的耦合,因为不可变对象必须完全管理其自身的状态,因此其行为类似于普通值。常量正确性极大地简化了证明程序正确性的过程,尤其是在并发编程的情况下。使用C ++引用和C ++ 0x右值引用语义,您可以使用不可变的对象,而不必担心在各处复制它们的开销。此外,如果您使用的是大多数不可变的对象,则编译器可以发挥一些非常神奇的优化魔术作用。
我知道它const
到处都是打字的麻烦,但是您很快就会习惯它,并且随着时间的流逝,就可靠性和可维护性而言,好处显而易见。我不是一个出色的作家,要证明这一点似乎是一项艰巨的任务,但是我知道const正确性对我作为开发人员在设计和实现程序时有极大的帮助,我认为经验是在这方面最好的老师。
mutable
,因为它在const正确性方面具有明确的含义。这意味着该数据对象可以以不影响对象行为的方式进行更改,并允许诸如缓存答案之类的事情。组成另一个关键字。
mutable
是合乎逻辑的选择。void alter(mutable Point&)
就像mutable int foo
对局部变量一样有意义,并且这些都不会与现有语言或的现有用法发生冲突mutable
。另外,Object mutable* mutable
看起来还很吓人,可以警告它是否必要或正确。
保持常量正确强调了设计的正确性,我将其视为不使用强制转换运算符的类似问题;因此,不要使用强制转换并保持const正确,最小化可变的用法-所有这些都是衡量设计水平的指针,而不是解决现有总体问题的实际工具。
PS:const
一旦我理解了使用的正确性,我就完全相信了;)
总结其他答案中涵盖的两点,并添加一个新的答案:
const
将代码记录给您的API用户。它在函数与其调用者之间形成契约,即该函数不会修改其参数。(请注意,该const_cast
功能不能使函数更改其参数,它允许将该参数传递给其他不修改其参数但忘记了const
注释的函数。)在函数/循环/等内部也很有用,因为它有助于理解很多内容。与循环不变的方式相同。
const
向编译器记录您的意图。在编译时发现错误总是比等待代码运行好。
const
类型安全多态性必需的。指针(所有形式,而不仅仅是原始指针)只有在它们是协变的情况下const
(注意:与“ const指针”不同)。协方差需要一个只读接口,而协方差需要一个只写接口。
我首先学习了其中的第二个。我const
仅从指针和引用参数的目标开始,直到我开始看到更早捕获错误并开始在局部变量上使用它的好处。
然后我了解到,大多数#define
s可以被全局常量替换(在C ++中),并具有类型安全的附加优点。所以我在那里也使用了它。
最终,我参加了有关类型系统和lambda演算的课程,并了解到const
和非const
类型在本质上是不同的(因为它们支持不同的操作),从那时起,我什至从未考虑过在不大量使用C的情况下编写C ++代码const
。
这是我没看到别人提到的5美分。传递变量时,除非确实需要,否则您不希望按值传递值,以避免额外的构造,破坏和复制。因此,除非您确实必须按值传递值,否则在各处都使用引用,即使您不打算更改传递的值也可以显着提高性能。出于这个原因,当您拥有引用其所有参数的函数时,需要让调用者知道该函数将不会被修改的内容。
它的原理相同,但是我只想添加使用const的实际原因。