const对具有可变成员的对象的引用

时间:2018-02-28 01:12:57

标签: c++ reference const mutable

假设我有一个具有mutable成员的类,并且我对该类的对象进行了多次const引用。标准是否保证这些引用将保持彼此同步?下面是一个例子。

动机:我相信我已经读过编译器有多个关于如何使用const引用来扩展对象生命周期的选项,其中一些实际上涉及复制对象(当然这可能会颠覆其中一个)首先使用参考文献的原因,但可能有必要保证对象的生存。如果这是真的,那么多个引用实际上是否可以像多个对象一样起作用(mutable成员的值不同)?

示例:

class A {
  public:
    mutable int x;
    A( const int x ) : x( x ) {}
    void f() const;  // Actually changes 'x'.
};

class B {
  public:
    const A & a;
    B( const A & a ) : a( a ) {}
    void f() const { a.f(); }
};

int main() {
  B * b1;
  B * b2;
  {
    A a( 0 );
    b1 = new B( a );
    b2 = new B( a );
  }

  // Do something that would change a mutable variable in 'b1.a' but possibly not in 'b2.a'.
  b1.f();

  return 0;
}

以下是我对此的解释。 a已经超出了范围,因此编译器必须要么“保持原始对象的存活”。不知何故(它与我对堆栈工作方式的基本理解并不完美混合)或为B的每个实例复制它(编译器假定它是安全的,因为它是{{1} })。但是,我做了一些可能改变其中一个实例的const部分的事情。此时mutableb1.a实际上会有所不同吗?

如果答案是"是,"那是合情合理的,因为我不希望这样。但如果答案是"不,"我对它的工作原理非常感兴趣。

1 个答案:

答案 0 :(得分:2)

由于引用绑定,您似乎期待终身扩展。不,谢谢。终身扩展适用于临时,而不是已存在范围和名称的对象。

即使您已经将临时转移到B的构造函数,它仍然只会被扩展到该语句的结尾 - the extension isn't transitive along a whole chain of reference bindings(并且它不适用于成员引用)。

因此,您尝试通过悬空引用访问数据,并且您的程序具有未定义的行为。期待任何结果,或没有结果。 constmutable都没有任何关系。

如果您想知道