类引用成员列表初始化

时间:2013-11-02 13:01:00

标签: c++ c++11

你能告诉我为什么不同编译器中该类引用成员的输出不同?

  class B
  {
     int& aRef;
     public:
     B(int c):aRef(c){}

     void Print()
     {
         cout<<aRef<<endl;
     }
  };

  void f(int s)
  {
    int& lcRef=s;
    cout<<lcRef<<endl;
  }

 int main()
 {
    int x=100;
    B s(x);
    s.Print(); //ms c++ output : 3323244, gcc output :100
    f(x);   //ms c++ output : 100, gcc output:100
    return 0;
 }


函数f(int s)的第二个问题参数与B类初始化的构造函数行为相同?

3 个答案:

答案 0 :(得分:5)

B(int c):aRef(c){}

这将绑定对构造函数参数c的引用。因为它是通过值传递的,所以当构造函数返回时它会被销毁,而引用会悬空。在构造函数返回后访问它会给出未定义的行为;在这种情况下,它会尝试访问一块已释放的堆栈内存,这些内存可能会或可能仍然无法访问,并且可能包含或不包含旧值。

您希望通过引用传递,以绑定到调用者的变量:

B(int& c) : aRef(c) {}

答案 1 :(得分:4)

f函数是正确的,并按预期工作,但在这里:

B(int c):aRef(c){}

您基本上将int& aRef地址分配给本地自动分配变量(c)。现在,引用比指针更安全,但是指定一个超出范围的自动分配变量是使它们无效的少数情况之一。

GCC输出正确的事实并不意味着什么,因为该变量在构造函数之外不再有效。

答案 2 :(得分:2)

不同之处在于 f内的,您正在参考参数。通过引用打印内容时,此参数仍然有效。对于B的构造函数,您存储引用,当构造函数完成时,引用的对象超出范围,因此引用变为悬空引用并使用它变为无效。海湾合作委员会的输出只是巧合,但并不能保证。