1

クラスの参照メンバーの出力がコンパイラによって異なる理由を教えてください。

  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;
 }


関数の 2 番目の質問パラメーターはf(int s)、クラス B の初期化のコンストラクターと同じロジックで動作しますか?

4

3 に答える 3

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

これにより、参照がコンストラクタ引数にバインドされますc。値で渡されるため、コンストラクターが戻ると破棄され、参照がぶら下がったままになります。コンストラクターが戻った後にアクセスすると、未定義の動作が発生します。この場合、まだアクセスできる場合とできない場合があり、古い値が含まれている場合と含まれていない場合がある、割り当て解除されたスタック メモリの塊にアクセスしようとします。

参照渡しして、呼び出し元の変数にバインドします。

B(int& c) : aRef(c) {}
于 2013-11-02T13:09:33.827 に答える
4

f関数は正しく、期待どおりに動作しますが、ここでは:

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

基本的にint& aRef、アドレスをローカル自動割り当て変数 ( c) に割り当てています。現在、参照はポインターよりも安全ですが、スコープ外になる自動割り当て変数の割り当ては、それらを無効にする数少ないケースの 1 つです。

出力が GCC で正しいという事実は、その変数がコンストラクターの外では有効ではないため、何も意味しません。

于 2013-11-02T13:06:26.913 に答える
2

違いは、 fではパラメータへの参照を取得していることです。このパラメーターは、参照を通じてコン​​テンツを印刷する場合でも有効です。のコンストラクターのB場合、参照を格納していて、コンストラクターが終了すると、参照先のオブジェクトがスコープ外になるため、参照がダングリング参照になり、使用が無効になります。GCC からの出力は単なる偶然ですが、保証するものではありません。

于 2013-11-02T13:08:27.313 に答える