常量引用如何工作?

时间:2017-06-24 14:09:16

标签: c++ pass-by-reference

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

3 个答案:

答案 0 :(得分:7)

  

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

不完全。您不能修改对象 const &。换句话说,您具有只读访问权限。但是没有任何东西本身阻止其他具有读写访问权限的代码(例如引用对象的原始所有者)来修改它。在设计时你需要小心,这样的改变不会让你感到惊讶。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

  

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

最好将其称为对常量对象的引用。这使事情更加清晰。反过来调用它只会让人感到困惑,因为任何引用都是常量(意味着你不能让它在初始化后引用另一个对象)。

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

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

  • 只读取对象的成员变量,但不分配给它们,除非成员被标记为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 );
}