0

私のゲームのメインループは次のようになります。

std::vector<std::unique_ptr<State>> states;

for(size_t i = 0; i < states.size(); i++)
{
     states[i]->Update();
     states[i]->Draw();

}

しかし、彼らはこれの欠陥です。反復中にベクトルを変更(状態を削除)することはできません。現在の状態を削除すると、反復がオンになり、updateを呼び出して描画する状態がないため、明らかに壊れます。statesそのため、ベクトルに追加する必要のある状態のベクトルを作成し、ベクトルに削除する必要のある状態のベクトルを作成することをお勧めしstatesます。次に、ループが終了した後、statesベクトルを変更すると、反復の途中で問題が発生することはありません。

std::vector<std::unique_ptr<State>> states;
std::vector<std::unique_ptr<State>> statesToBeAdded;
std::vector<std::unique_ptr<State>> statesToBeRemoved;

for(size_t i = 0; i < states.size(); i++)
{
    states[i]->Update();
    states[i]->Draw();

}

for(size_t i = 0; i < statesToBeAdded.size(); i++)
{
    states.push_back(std::move(statesToBeAdded[i]));
}
statesToBeAdded.clear();

for(size_t i = 0; i < statesToBeRemoved.size(); i++)
{
    states.erase(std::remove(states.begin(), states.end(), statesToBeRemoved[i]), states.end());
}
statesToBeRemoved.clear(); //error is thrown here

ベクトルから状態を削除することはできませんが、行statesにエラーがスローされます。これは、行を呼び出すと、ベクトルから要素が削除され、その要素がベクトルを指しているため、ベクトル内の同じ要素が無効になるstatesToBeRemoved.clear()ためだと思います。存在しなくなったオブジェクト。states.erase(...)statesstatesToBeRemoved

ポインタが指しているものを破壊せずにstd::unique_ptrを削除することはできないので、statesベクトル内の要素を無効にせずにベクトルから要素を削除する方法はないと思いますstatesToBeRemoved。では、この問題をどのように解決するのでしょうか。

ありがとう。

4

1 に答える 1

0

さまざまなポインタタイプがさまざまな所有権セマンティクスに対応します。

  • unique_ptrsは一意の所有権のためのものであり、これが現在のコードが機能しない理由です
  • shared_ptrsは共有所有権用です-オブジェクトを最後にshared_ptr管理することがスコープ外になると、オブジェクトは破棄されます
  • 生のポインタ(*)は、モデリングしているセマンティクスについて実際には何も言いませんが、すべての制約を手動で適用する必要があります。これが、それらを危険なものにしている理由です。ただし、ポイントされたオブジェクトの所有権を持たないポインターに対しては安全です(そして私の意見では賢明な選択です)。

だから:あなたstatesToBeAddedがまだ入っていないものがそこに決してないことを保証できる限り、あなたは安全ですstatesstatesToBeRemovedは異なります。オブジェクトはすでにそこにあり、オブジェクトの所有権を取得statesすることは理にかなっています。statesしたがって、生のポインタはの適切な選択ですstatesToBeRemoved

Stateこれはすべて、表示した数行のコードに基づいていることに注意してください。状況によっては、などにsの代わりにunique_ptr<State>sを格納するのが理にかなっている場合がありますstates...

于 2013-02-21T00:08:12.013 に答える