2

私はC++に比較的慣れていないので、次の場合に構造体がコピーされるかどうか疑問に思っています:

struct foo {
  int i;
  std::vector<int> bar;
}

class Foobar {
  foo m_foo;

  void store(foo& f) {
    this->m_foo = f;
  }
}

void main() {
  Foobar foobar;
  {
    foo f;
    f.i = 1;
    f.bar.insert(2);
    foobar.store(f);
  }
  // will a copy of f still exist in foobar.m_foo, or am I storing a NULL-Pointer at this point?
}

私がこれを尋ねている理由は、私が元々 .NET 開発者であり、.NET 構造体を関数に渡すとコピーされる (そしてクラスはコピーされない) ためです。store が参照によって f を取るように宣言されていない場合、コピーされると確信していますが、このコードを変更することはできません。

編集:vector.insert私の質問に影響を与えるとは知らなかったので、コードを更新しました。私の場合、構造体をベクトルではなくクラスのメンバーとして保存します。だから私の質問は本当に:fにコピーされthis->m_foo = f;ますか?

4

3 に答える 3

5

簡単な答え: はい。

長い答え:スタックに割り当てられた構造体へのポインターを取得し、その構造体をスコープ外に出して、ベクター内のダングリング参照を終了する必要があります...しかし、それでも、保存していないでしょうNULL。_ C および C++ ポインターは単純なものであり、コードがそれらを上書きしない限り、そのメモリー位置が無効になった後もずっとそのメモリー位置を指し続けます。

std::vectorこの場合、暗黙的に呼び出されるコピーおよび移動関数の適切なセットが関連付けられていることも注目に値するかもしれません。そのためbar、構造体内のベクトルも単純な整数とともにコピーされiます。標準ライブラリ クラスは非常によく書かれている傾向がありますが、他の人々によるコードはそのような保証はありません!

さて、あなたの編集に関して:

class Foobar {
  foo m_foo;

 void store(foo& f) {
    this->m_foo = f;
  }
}

に格納されているインスタンスに問題はありません。これは、参照型またはポインター型の変数ではないため、コピー操作を呼び出すためです。代わりにこれを使用すると、インスタンスをコピーする代わりにインスタンスへの参照をコピーすることになり、そのインスタンスがスコープ外になると参照が無効になるため、問題が発生します。foom_foothis->m_foo = fm_foofoo& m_foofoofoo

于 2012-11-14T11:42:34.253 に答える
3

はい、次の関数で構造体がコピーされます。

foos.insert(f);

コピーが作成されると、null ポインター/null 参照は格納されません。

ただし、あなたが言ったように、関数は引数を参照として受け入れるため、呼び出すときにコピーされません。store(f);

編集によって Foo のコピーが作成されます。変数の 1 つのインスタンスを変数の別のインスタンスに割り当てています。あなたがしていないのは、1 つのポインター (C# での参照) を別のポインターに割り当てることです。おそらく、C++ オブジェクトのインスタンス、ポインター、および参照に関するいくつかの読み取りを行うことで対処できます。

于 2012-11-14T11:40:16.583 に答える
2

のコピーfが作成されます。foos.insert(f)

void store(foo& f) {
  foos.insert(f);
}

void main() {
  {
    foo f;
    f.i = 1;
    f.bar.insert(2);
    store(f);
  }
  // at this place, local variable `f` runs out of scope, it's destroyed and cleaned up
  // foos is holding the copy of `f`
}
于 2012-11-14T11:39:47.737 に答える