【问题标题】:Should I declare a parameter that will never be changed as a const variable? [duplicate]我应该将永远不会更改的参数声明为 const 变量吗? [复制]
【发布时间】:2012-03-02 01:40:32
【问题描述】:

可能重复:
Use of 'const' for function parameters

例如,

void Func(int para);

如果我知道我不想在 Func(...) 中更改 para 的值,我是否应该改为将 para 声明为“const int”以保证这一点?即

void Func(const int para);

顺便说一句,我认为

void Func(const int &para);

有时不是一个合适的选择,因为 const int& 通常由底层指针实现,因此它本质上等同于

void Func(const int *p_para);

“C++ 编码标准:101 条规则”一书 p31 说“void Func(const int para);”不好,因为它会“混淆”头文件的读者。不过我不确定……

经过深思熟虑,我认为一个好的解决方案是将其声明为“void Func(int para);”并在实现时使用“void Func(const int para) {...}”。我发现“void Func(const int para);”中的“const”一词将被编译器静默删除...

【问题讨论】:

标签: c++


【解决方案1】:

const int para: 对你有用,因为它可以防止你错误地修改 para。不确定混淆问题。

const int &para:你应该这样做,实际上有时你必须这样做,如果其他地方的代码坚持让你保持para 不变(例如,如果你正在为map 编写自定义比较器函数)。也比const int para效率高——如果不修改para为什么还要复制呢?

我认为const int &para 在下面的实现并不重要。重要的是,在上面你不能修改它(不作恶),所以效果和const int para一样,但效率更高。

【讨论】:

  • 不,没有代码会坚持你这样做。您将此与 const-ref 参数混淆了。
  • 我很确定引用通常由指针实现。您可以在en.wikipedia.org/wiki/Reference_(C%2B%2B) 找到信息
  • 当然,它们下面的指针,但这无关紧要,因为在上面,编译器不会让你改变它们指向的东西,而且它们不能null 或未初始化。从软件工程的角度来看,这些东西将它们与指针区分开来:它们通常使用起来更安全。
【解决方案2】:

我认为它只会为头文件的读者澄清一些事情,通过标记参数const 它实际上是在说它只是输入。同样,& 引用运算符被读取为函数中正在修改的参数,对传递的参数产生影响。这可能是引起混淆的地方,但是 const int &paraconst “之前”它是 & 参考,不需要太多解释。

我混淆了&* 表示法,因为我习惯于不存在& 运算符的C。但是对于 C++,我建议你使用它。

【讨论】:

  • 与 Sideshow Bob 的评论相同,您对此感到困惑。标记参数const不是界面的一部分。
【解决方案3】:

将参数声明为const 有三个目的:

  1. 它告诉编译器该值是常量,这可能会启用某些优化。鉴于今天的“智能”编译器,我不确定它是否仍然相关。

  2. 它一目了然地告诉程序员该值在函数内不会改变,这可能有助于他们调试/增强代码。

  3. 它使编译器实际上强制执行您的断言,即函数不会更改值。

一般来说,如果可以的话,最好将变量声明为const,出于同样的原因,最好消除编译器警告:它使您的代码更易于支持。

【讨论】:

  • 我认为这从未启用任何优化。不过第 2 点和第 3 点很好。
  • 由于参数是int(与可能具有复杂构造函数的对象相反),编译器不需要复制值以在函数中使用;它可以直接使用调用者变量的内容。
  • @KonradRudolph 我怀疑const 的参数可以用作restrict 的钝版。也就是说,如果编译器认为通过地址传递给函数的几个读写参数可能指向同一个地址,但如果它们是只读的则无关紧要。我不确定这种情况是否确实存在。
  • 有一个可能的优化,不需要复制。
【解决方案4】:

如果你这样做(有些人这样做),那么你应该将 const 放在定义中(它有用的地方)而不是声明(它是噪音,它不会影响调用者)。

所以:

void F(int param);

...


void F(int const param) {
   ...
}

【讨论】:

  • 没错。如果你在声明中使用了 const 而在定义中没有使用,你仍然可以修改变量,即声明中的 const 将被忽略。
【解决方案5】:

你不应该。在 C 中,参数是按值传递的,所以调用者不需要知道你对它传递的 int 做了什么。即使您的函数是void func(int),您也可以将const int 传递给它。

void func(int a) {
 a=5;
}
...
const int b=7;
func(b);

在此代码中,b 仍为 7,因为该函数仅更改了局部变量 a

当然,如果函数得到一个指针或引用,那就不同了。如果声明是void func(int &a),那么上面的代码是非法的,因为func改变了b,它是const,因此如果你的函数没有改变引用,并且你希望有可能传递一个@987654330 @给它,你应该将参数声明为const。

【讨论】:

  • 不,你应该。只是不在声明中。
猜你喜欢
  • 1970-01-01
  • 2013-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多