你走多远const?您是否只是const在必要时制作功能,或者您是否全力以赴并在任何地方使用它?例如,想象一个简单的mutator,它接受一个布尔参数:
void SetValue(const bool b) { my_val_ = b; }
Run Code Online (Sandbox Code Playgroud)
这const实际上有用吗?我个人选择广泛使用它,包括参数,但在这种情况下,我想知道它是否值得?
我还惊讶地发现你可以省略const函数声明中的参数,但可以将它包含在函数定义中,例如:
.h文件
void func(int n, long l);
Run Code Online (Sandbox Code Playgroud)
.cpp文件
void func(const int n, const long l)
Run Code Online (Sandbox Code Playgroud)
是否有一个原因?这对我来说似乎有点不寻常.
我的同事是0 2上的问题,他一直激励着(1,2),所以我想我应该给他一个机会,迎头赶上.
我们最近的分歧是关于将"const"放在声明上的样式问题.
他认为它应该在类型前面,或者在指针之后.原因在于,这是其他人通常所做的事情,其他风格可能会让人感到困惑.因此,指向常量int的指针和指向int的常量指针将分别为:
const int *i;
int * const i;
Run Code Online (Sandbox Code Playgroud)
但是,无论如何我很困惑.我需要的是一致的,易于理解的规则,我可以做的"常量"意义上的唯一方法是,它去后,它被修改的事情.有一个例外允许它在最终类型前面,但这是一个例外,所以如果我不使用它,它会更容易.
因此,指向常量int的指针和指向int的常量指针将分别为:
int const * i;
int * const i;
Run Code Online (Sandbox Code Playgroud)
作为一个额外的好处,以这种方式做事使得更深层次的间接更容易理解.例如,指向int的常量指针的指针显然是:
int * const * i;
Run Code Online (Sandbox Code Playgroud)
我的论点是,如果有人只是按照自己的方式学习,他们就可以轻松搞清楚上面的内容.
这里的最终问题是他认为将int放在int之后是如此难以言喻的丑陋,对可读性有害,以至于它应该在样式指南中被禁止.当然,我认为如果指南应该建议按照我的方式做,但无论哪种方式,我们都不应该禁止一种方法.
编辑: 我已经得到了很多好的答案,但没有一个真正直接解决我的最后一段("最终问题").很多人都争论一致性,但在这种情况下是如此理想,禁止其他方式这样做是一个好主意,而不是仅仅劝阻它?
在以下C++函数中:
void MyFunction(int age, House &purchased_house)
{
...
}
void MyFunction(const int age, House &purchased_house)
{
...
}
Run Code Online (Sandbox Code Playgroud)
哪个更好?
在两者中,'年龄'都是按价值传递的.我想知道'const'关键字是否有必要:对我来说似乎是多余的,但也很有用(作为额外的指示,变量不会改变).
有没有人对上述哪个(如果有的话)更好有任何意见?
我最近与另一位C++开发人员就以下用途进行了交流const:
void Foo(const int bar);
Run Code Online (Sandbox Code Playgroud)
他认为const以这种方式使用是很好的做法.
我认为它对函数的调用者没有任何作用(因为参数的副本将被传递,因此对于覆盖没有额外的安全保证).此外,这样做可以防止实现者Foo修改其参数的私有副本.因此,它既要求又要宣传实施细节.
不是世界末日,但肯定不是值得推荐的良好做法.
我很好奇别人对这个问题的看法.
好吧,我没有意识到参数的常数没有考虑到函数的签名.因此,可以const在实现(.cpp)中标记参数,而不是在标题(.h)中标记- 并且编译器就可以了.既然如此,我想政策应该与制作局部变量const相同.
人们可以提出这样的论点:在标题和源文件中具有不同的看起来签名会使其他人感到困惑(因为它会使我感到困惑).虽然我试着用我写的任何内容来遵循最小惊讶原则,但我认为期望开发人员认为这是合法且有用的是合理的.
我确实理解了const必须通过引用函数传递的指针或结构的含义.但是在示例中:
void foo(const int a);
Run Code Online (Sandbox Code Playgroud)
变量a在堆栈上传递.调用者修改堆栈内容没有坏处,因此const在这种情况下看起来很无用.
此外,如果我无法修改a,我仍然可以复制一份并更改此副本:
void foo(const int a)
{
int b = a;
b++;
}
Run Code Online (Sandbox Code Playgroud)
在const应用于标量函数参数(不是指针)时,关键字在哪种情况下会有用?
说你有:
int f( const T a ) { ... }
int g( const T &a ) { ... }
Run Code Online (Sandbox Code Playgroud)
我理解constin的用法g:我们不知道a函数外是如何使用的,所以我们想保护它不被修改。但是我不明白constin的使用f,哪里a是本地副本。为什么我们需要保护它不被修改?
我有一个探测数组的函数,如果探测成功,则返回一个数组索引.
在我的代码中,type_t为了清楚起见,我已经为数组索引a制作了所有类型.
保留此功能的清晰度的优先方法是什么?我应该将一个指针参数带到一个错误变量并设置它吗?
inline size_t
lin_search(const double *pxa, const double x, const size_t idxlow, const size_t idxhigh)
{
for (size_t i = idxlow; i < idxhigh; i++)
{
if (pxa[i] <= x && pxa[i+1] > x)
return i;
}
return -1; // If I change the return type to f.ex long int this works
// but I am no longer consistent
}
Run Code Online (Sandbox Code Playgroud)
然后我可以用它作为
index = linsearch(parray, x, 0, n - 1);
if (index == -1)
... not found
Run Code Online (Sandbox Code Playgroud) 我想更好地了解如何更改函数签名:
void foo(double x);
Run Code Online (Sandbox Code Playgroud)
至:
void foo(const double x);
Run Code Online (Sandbox Code Playgroud)
如果我们不修改x里面,可能会导致代表编译器的一些优化技巧.有人可以给我一个具体的具体例子吗?