2

以下の 2 つのコード スニペットを確認してください。サンプル 2 では、ローカル変数の ref が渡されるため、明らかにダングリング参照の問題が存在しますが、サンプル 1 にも同じ問題があると思いますか? 私自身は、サンプル 1 が正しいと思います。データがデータ構造 ( ) にプッシュされている間に、参照が取得されました ( isstl::queueの関数ヘッダー)。したがって、ここからデータを返す際に問題は発生しません。それともありますか?enqueuevoid enqueue(const int &data)&data

サンプル 1:

int const& dequeue()
{
    _mutex.lock();
    int &data = _queue.back();
    _queue.pop();
    _mutex.unlock();
    return data;
}

サンプル 2:

int const& dequeue()
{
    _mutex.lock();
    int data = _queue.back();
    _queue.pop();
    _mutex.unlock();
    return data;
}
4

1 に答える 1

1

サンプル1は正しくありません。

を呼び出すと、参照は無効になりますpop()

関数が返す参照は、関数の終了時にまだ有効なオブジェクトへの参照である必要があります。

これは、サンプル2が正しくないことも意味しますが、あなたが考える理由ではありません。はい、その参照を返すことは無効です(コンパイルすらすべきではありません)がdata、関数が終了する前は無効です-繰り返しますが、呼び出しの直後に、pop()そのコンテナー内のオブジェクトへの参照はすべて無効になります。

参照で戻ってくる理由はありますか?あなたは明らかに値がまったく変化することを期待していません、そしてあなたの参照はですconst、それでなぜ単に値で返すのではないのですか?

int dequeue()
{
    _mutex.lock();
    int data = _queue.back();
    _queue.pop();
    _mutex.unlock();

    return data;
}

ローカルで宣言された参照を返すことについてのより一般的な質問への回答として、関数が終了した後も参照するオブジェクトが引き続き有効である限り、それは問題ありません。例えば:

int glob;

int& f(){
  int x;
  int& ref = glob;
  return x;
}

int main(){
  foo()=10;  //this is fine
}
于 2011-06-22T01:22:17.373 に答える