【问题标题】:How do constant references work?常量引用是如何工作的?
【发布时间】:2017-11-27 23:13:59
【问题描述】:

最近我一直在学习 C++ 的良好编程实践,发现许多程序通过引用将对象传递给函数,因此不会创建多个实例。我还了解到,传递一个常量引用可以防止原始对象被修改,但是我不明白它是如何工作的。常量引用不应该创建一个新实例,因为原始对象不能通过引用修改,但引用仍然可以像单独的对象一样使用?我相当肯定这不是它的工作方式,但是,它是如何工作的?有什么我错过的吗?

【问题讨论】:

  • 似乎“传递一个常量引用可以防止原始对象被修改”的奇怪信念有一些流行。不,常量引用会阻止修改原始对象。它只是防止对象被修改通过引用
  • 从我已链接的问题的答案中 有“const 引用”实际上是“对 const 的引用”,也就是说,您无法更改它们引用的对象的值到。
  • How C++ reference works的可能重复

标签: c++ pass-by-reference


【解决方案1】:

常量引用不应该创建一个新实例,因为 原始对象不能通过引用修改,但 引用仍然可以像单独的对象一样使用吗?

最好将其称为对常量对象的引用。这使得事情的工作原理更加清晰。以相反的方式调用它只会令人困惑,因为 any 引用是恒定的(这意味着您不能让它在初始化后引用另一个对象)。

因此,对常量对象的引用只是现有对象的附加名称(如非常量引用),其限制是该名称仅允许读取来自现有对象。

这意味着通过对常量对象的引用,您可以:

  • 只从对象的成员变量中读取,而不是赋值给它们,除非一个成员被标记为mutable
  • 只调用标记为const的对象的方法

示例:

struct Foo
{
    int a;
    mutable int b;

    void SetA( int newA ) { a = newA; }
    int GetA() const      { return a; }
};

void DoSomething( const Foo& f )
{
    // Here, f is just another name for foo, but it imposes some restrictions:
    f.a = 42;          // compiler error, can't modify member!
    f.SetA( 42 );      // compiler error, can't call non-const method!
    int x = f.a;       // OK, reading is allowed.
    f.b = 42;          // OK, because b is marked as mutable
    int y = f.GetA();  // OK, because GetA() is marked as const 
}

int main()
{
    Foo foo;
    DoSomething( foo );
}

【讨论】:

    【解决方案2】:

    常量引用 (const&) 类似于指向常量对象的指针。您可以通过参考阅读它,但不能修改它。其他持有-const引用可以仍然可以修改它。

    【讨论】:

      【解决方案3】:

      我还了解到,传递常量引用可以防止原始对象被修改 [...]

      不完全是。您不能通过const & 修改对象。换句话说,您具有只读访问权限。但是没有什么能阻止其他具有读写访问权限的代码(例如被引用对象的原始所有者)对其进行修改。您在设计时确实需要小心,以免此类更改让您感到惊讶。

      【讨论】:

      • 感谢您的回答,我没有意识到常量引用只是只读的。我也更新了问题,因为我知道可以通过其他方式修改对象。
      猜你喜欢
      • 1970-01-01
      • 2012-02-21
      • 2012-04-01
      • 2013-01-07
      • 1970-01-01
      • 1970-01-01
      • 2011-10-07
      • 2020-06-28
      相关资源
      最近更新 更多