0

いくつかのメモリを割り当て、同じタイプのオブジェクトのセットで埋めたとしましょう。これらのコンポーネントを呼び出します。

これらのコンポーネントの1つを削除する必要があるとしましょう。コンポーネントによって作成された「穴」をテストし、オブジェクトのセットを反復するループでスキップできるようにするための良い方法は何でしょうか。

逆もまた真であるはずです。スペースに新しいコンポーネントを格納するために、穴をテストできるようにしたいと思います。

私はmenclearを考えており、0をチェックしています...

4

6 に答える 6

3

boost::optional<component>あなたのニーズにぴったり合っているようです。それが何であれ、それらをあなたのストレージに入れてください。たとえば、std::vector

// initialize the vector with 100 non-components
std::vector<boost::optional<component>> components(100);

// adding a component at position 15
components[15].reset(component(x,y,z));

// deleting a component at position 82
componetnts[82].reset()

// looping through and checking for existence
for (auto& opt : components)
{
    if (opt) // component exists
    {
        operate_on_component(*opt);
    }
    else     // component does not exist
    {
        // whatever
    }
}

// move components to the front, non-components to the back
std::parition(components.begin(), components.end(),
    [](boost::optional<component> const& opt) -> bool { return opt; });
于 2013-01-14T19:55:16.003 に答える
0

簡単に言えば、それはあなたがそれをどのように記憶に保存するかに依存するということです。

たとえば、ANSI規格は、ベクトルを連続して割り当てることを提案しています。

オブジェクトのサイズを予測できる場合は、size_ofやaddressingなどの関数を使用して、メモリ内の場所を予測できる可能性があります。

幸運を。

于 2013-01-14T19:32:07.347 に答える
0

少なくとも2つの解決策があります。

1)穴にフラグを付けて、処理時にスキップします。利点:「削除」は非常に高速です(フラグを設定するだけです)。オブジェクトがそれほど小さくない場合は、「boolalive」フラグを追加してもそれほど難しくはありません。

2)プールの端にある穴を移動し、「生きている」オブジェクトに置き換えます。

この問題はパーティクルシステムの保存と処理に関連しているので、そこにいくつかの提案があります。

于 2013-01-14T19:35:07.523 に答える
0

「ライブ」コンポーネントを上に移動できない場合、またはシーケンスの途中に穴がないようにそれらを並べ替えることができない場合は、コンポーネントオブジェクトに「削除済み」フラグ/状態を与える場合の最良のオプションです。メンバー関数を介してテストされます。
このような「削除済み」状態では、オブジェクトがメモリから削除されることはありませが(大きなブロックの途中では不可能です)、コンポーネントに使用されていないスポットをマークすることはできます。

于 2013-01-14T19:35:23.160 に答える
0

「メモリを割り当てた」と言うときは、配列について話している可能性があります。配列は、実質的にオーバーヘッドがなく、インデックスによるアクセスが非常に高速であるため、優れています。しかし、配列の悪い点は、サイズ変更にあまり適していないことです。中央の要素を削除すると、後続のすべての要素を1つ戻す必要があります。

ただし、幸いなことに、リンクリストバイナリツリーなど、要素をすばやく削除できる他のデータ構造を使用できます。C ++は、これらをコンテナクラスstd::listおよびstd::setに実装します。

リストは、必要な要素の数が事前にわからない場合に最適です。要素を削除または追加するときにメモリを無駄にすることなく、動的に縮小および拡大できるためです。また、要素の追加と削除は、最初、最後、または途中のどこかに挿入しても、非常に高速です。

セットはクイックルックアップに最適です。オブジェクトがあり、それがすでにセットに含まれているかどうかを知りたい場合は、非常にすばやくチェックできます。セットはまた、重複を自動的に破棄します。これは、多くの状況で非常に役立ちます(重複が必要な場合は、std :: multisetがあります)。リストと同じように動的に適応しますが、新しいオブジェクトの追加はリストの場合ほど速くはありません(ただし、配列の場合ほど高価ではありません)。

于 2013-01-14T19:39:52.010 に答える
0

2つの提案:

1)リンクリストを使用してコンポーネントを保存でき、穴の心配がありません。

または、これらの穴が必要な場合:

2)次のように、コンポーネントへのポインタを使用して、コンポーネントをオブジェクトにラップできます。

class ComponentWrap : public
{
   Component component;
}

ComponentWrap.component == nullコンポーネントが削除されているかどうかを確認するために使用します。

例外的な方法:

3)nullポインターエラーが発生した場合に備えて、コードをtrycatchブロックに配置します。

于 2013-01-14T19:41:56.563 に答える