为什么引用成员变量会相互覆盖?

时间:2014-12-08 10:03:29

标签: c++ reference

在下面的代码中,Var的两个实例的_bla成员似乎代表相同的内存位置,因为在一个实例上设置值也会改变另一个实例。执行程序时,输出为:

v: 44 v2: 44 x: 22

有人可以解释一下吗?

#include <iostream>

using namespace std;

template<typename T> class Var {
  T  &_bla;
public:
  Var(T t) : _bla(t) {}

  int bla() const {
    return _bla;
  }
};

using namespace std;

int main() {
  cout << "Hello, World!" << endl;

  int x = 22;
  Var<int> v = {x};
  Var<int> v2 = {44};

  cout << "v: " << v.bla() << " v2: " << v2.bla() << " x: " << x << endl;
  return 0;
}

3 个答案:

答案 0 :(得分:7)

未定义的行为,这意味着一切皆有可能。

ctor的参数t按值传递,它将从参数复制,然后通过引用分配给_bla,当超出ctor的范围时,参数{{ 1}}被解除分配,现在成员变量t成为悬空引用。

您可以重新考虑您的设计,您是否需要成员变量作为参考?参数类型_bla应该是什么?通过const引用,通过引用,按值? (在你的情况下,按值传递它显然是错误的。)当你使用成员变量的引用时,最好仔细考虑。

答案 1 :(得分:2)

我看到它的方式,它们实际上引用了Var的构造函数的参数,它是一个碰巧位于同一内存位置的临时副本,甚至可能在程序中稍后被覆盖。

如果您的membervariables应该引用非成员变量,则必须通过引用传递它。但是,在大多数情况下,这是一个非常糟糕和危险的设计。

答案 2 :(得分:0)

以下代码更有意义:

template<typename T> class Var {
    T  _bla;
public:
    Var(const T & t) : _bla(t) {}

    int bla() const {
        return _bla;
    }
};

基本上,班级会按值保留副本。

在原始代码中,您正在引用在实际打印其值之前销毁的临时对象。因此,它是未定义的行为。