尽可能保持"常量"是一个好主意吗?

iam*_*ind 11 c++ coding-style const

最近,我一直在开发一种在我的代码中做很多事情的做法const:

(1)功能论证,我知道永远不会改变.例如:

void foo (const int i, const string s)
          ^^^^^        ^^^^^ 
Run Code Online (Sandbox Code Playgroud)

(2)返回类型const.例如:

struct A {
...
  const int foo () { return ...; }
  ^^^^^
  operator const bool () const { return ...; }
           ^^^^^
};
Run Code Online (Sandbox Code Playgroud)

(3)整数或字符串的平凡计算.例如:

const uint size = vec.size();
^^^^^
const string s2 = s1 + "hello ";
^^^^^
Run Code Online (Sandbox Code Playgroud)

......还有更多的地方.通常在其他现实世界的代码中,我没有看到标记为的这种小规模变量const.但我想,让它们const永远不会受到伤害.这是一个很好的编程习惯吗?

Ste*_*sop 14

(1)和(3)密切相关.by-value参数只是具有该名称的局部变量,这是计算的结果.

通常,无论是否标记局部变量,短函数都没有什么区别const,因为您可以看到它们的整个范围就在您面前.您可以查看值是否更改,您不需要或希望编译器强制执行它.

但是,它偶尔会有所帮助,因为它可以防止您意外地将它们传递给通过非const引用获取其参数的函数,而不会意识到您正在修改变量.因此,如果您将变量作为函数参数在其生命期间传递,那么标记它const可以让您更自信地知道它之后具有什么值.

偶尔,标记变量const可以帮助优化器,因为你告诉它对象永远不会被修改,有时这是真的,但编译器无法以其他方式证明它.但由于这个原因,它可能不值得这样做,因为在大多数情况下它没有任何区别.

(2)是另一回事.对于内置类型,它没有区别,正如其他人所解释的那样.对于类类型,不要返回const值.这似乎是一个好主意,因为它可以防止用户写一些毫无意义的东西func_returning_a_string() += " extra text";.但它也阻止了一些有意义的东西--C++ 11移动语义.如果foo返回一个const字符串,我写std::string s = "foo"; if (condition) s = foo();,然后我得到复制赋值s = foo();.如果foo返回非const字符串,那么我得到移动赋值.

类似地,在没有移动语义的C++ 03中,它阻止了称为"交换优化"的技巧 - 使用非const返回值foo().swap(s);而不是s = foo();.


Pla*_*aHH 7

是.

在编程语言中表达您的意图总是一种很好的编程习惯.您不打算更改变量,因此请将其设为const.稍后,当你的编译器向你大吼大叫,当它是const时你无法修改它,你会很高兴编译器发现了你自己设计的一些错误想法.这不仅适用于const,也适用于许多其他内容,例如,为什么在C++ 11 override中引入了关键字.

当然有些情况下const不会改变任何东西,比如当你返回一个时int,但就像在其他安全区域一样:更好的是有一个const太多(你可能以后删除因为它不是真的需要),而不是有一个太少(这会突然破坏东西).