【问题标题】:const objects as a function parameterconst 对象作为函数参数
【发布时间】:2014-06-28 19:35:43
【问题描述】:

考虑以下代码sn-p:

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 上使用-Wall -std=c++11 尝试了 GCC (4.8.2) 和 Clang (3.4),结果相同(没有错误/警告)。我还搜索了“c++ const object function”,但没有得到任何看起来有希望的东西。

【问题讨论】:

  • 为什么它不应该接受非常量参数?可以不更改非常量对象。

标签: c++ constants


【解决方案1】:

这是完全理智和正常的。该对象在您的函数中被视为const;没关系,它最初不是不可变的。

当然,反之亦然!

void foo(T& rarr);

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

【讨论】:

    【解决方案2】:

    const 在这种情况下所做的只是防止修改参数变量(在类的情况下,防止调用未标记为const 的函数)。 MyClass 可以简单地转换为const MyClass,因为对于const MyClass 不应该对非const 做任何事情。当然,反过来是不正确的。

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-23
        相关资源
        最近更新 更多