Const对象作为函数形参

const objects as a function parameter

本文关键字:函数 形参 对象 Const      更新时间:2023-10-16

考虑以下代码片段:

class MyClass {
    int x;
  public:
    MyClass(int val) : x(val) {}
    const int& get() const {return x;}
};
void print (const MyClass& arg) {
  cout << arg.get() << 'n';
}
int main() {
  MyClass foo (10);
  print(foo);
  return 0;
}

无论我是否在MyClass的初始化之前添加const修饰符,程序都会成功编译(没有任何警告)并打印10。为什么print可以接受非const的论点?或者,换句话说,函数参数中const修饰符的作用是什么?为什么函数的形式参数和实际参数可以有不同的类型(或修饰符)?

我在Ubuntu 14.04上尝试了GCC(4.8.2)和Clang(3.4)与-Wall -std=c++11,结果是相同的(没有错误/警告)。我还搜索了"c++ const对象函数",但没有得到任何看起来有希望的东西。

这是完全正常的。该对象在函数中被视为const;它不是最初创建为不可变的,这并不重要。

当然,相反的是不正确的!

void foo(T& rarr);
int main()
{
   const T lolwut;
   foo(lolwut);   // oops
}

const禁止函数体修改参数变量。这两种方法都可以编译,因为您没有尝试修改它。

可以重载const和非const引用形参,只有当实参确实是const(或者类型转换导致传递临时类型)时,才会选择const重载。(对于非引用形参,const很少有意义,甚至可能没有定义这种重载)

在这种情况下,const所做的就是防止修改参数变量(并且在类的情况下,防止调用未标记为const的函数)。MyClass可以被简单地转换为const MyClass,因为你可以对const MyClass做任何你不能对非const做的事情。当然,反过来就不成立了。

(我在上面说"应该",因为如果你想的话,当然有可能在c++下完全颠覆const语义,所以函数原型中const的存在实际上只是一个有希望的提示,而不是一个铸铁的编译器强制的保证。)但是任何一个明智的程序员都不应该破坏这样的东西!)