2011-11-09 10 views
0

私はC++のゲームに取り組んでいます。私のレベルのオブジェクトはベクトルにあります(オブジェクトは私のレベルのオブジェクトのスーパークラスです)。C++:ポインタのベクトルを完全にコピー

このベクターの状態がチェックポイントに保存され、死んで取得される必要があります。

レベルの始めに、ベクター(オブジェクト)が作成されます(old_objects)。

チェックポイントにヒットした場合、old_objectsは消去され、オブジェクトはold_objectsに再コピーされます。

死亡した場合、オブジェクトからのデータは消去され、old_objectsはオブジェクトにコピーバックされます。

私はこれをいくつかの方法で実行しようとしてきましたが、それを動作させることはできません。助けて?

EDIT:仮想クローン()メソッドを使用してみました。範囲外のエラーが発生します。

class Object { 
    public: 
    virtual Object* clone() { return new Object(); } 
}; 

class SubObjectA { 
    public: 
    Object* clone() { return new SubObjectA(datablahblah); } 
}; 

class SubObjectB { 
    public: 
    Object* clone() { return new SubObjectB(datablahblah); } 
}; 

for (vector<Object*>::iterator it = objects.begin(); it != objects.end(); it++) { 
    Object* tempobj = *it; 
    old_objects.push_back(tempobj->clone()); 
} 

しかし、私が得るすべては同じ古いです:

terminate called after throwing an instance of 'std::out_of_range' 
    what(): vector::_M_range_check 

This application has requested the Runtime to terminate it in an unusual way. 
Please contact the application's support team for more information. 
+1

あなたは今まで正確に何を試しましたか? – krammer

+1

あなたはすでにどのように試してみましたか? –

+1

ポインタのベクトルについては、 'Boost.PointerContainer'を考慮する必要があります。 –

答えて

1

あなたはプロトタイプパターンを使用することができますし、あなたのオブジェクトの基本クラスは純粋仮想クローン()メソッドを宣言しています。その後、チェックポイント時には、ポインタ上のクローンを呼び出しているベクターを反復処理して、それらを新しいベクターにプッシュする必要があります。

+0

上記の編集を参照してください。 – Hinchy

+0

あなたの答えに関連するさらに詳しい情報を投稿に追加しました。 – Hinchy

+0

編集したコードがよさそうです。あなたは正しくold_objectsを初期化しましたか?間違っているのは難しいですが、他のすべてはうまく見えます。このプログラムはシングルスレッドで動作していますか?別のスレッドが実行されている場合は、オブジェクトの反復処理中にオブジェクトのベクトルを変更している可能性があります。 – zienkikk

0

ここで重要な要件は、すべての必要な情報を格納するディープコピーコンストラクタを提供することです(または、それが不可能な場合は、必要なすべての情報を取得するメソッド)。次に、そのctor /メソッドを使用して2番目のベクトルを作成します。何かのように:その後、

class Object 
{ 
    RenderObject * m_Renderable; 
    int m_Health; 
    float3 m_Position; 

    Object(const Object * other) : 
     m_Renderable(nullptr), 
     m_Health(other->m_Health), 
     m_Position(other->m_Position) 
    { }; 

    Object * GetStorable() 
    { 
     return new Object(*this); 
    } 
}; 

「チェックポイント」を格納するために、あなたは、単に実行します。

vector<vector<shared_ptr<Object>>> gCheckpoints; 
vector<shared_ptr<Object>> gLevelObjects; 

vector<shared_ptr<Object>> checkpoint; 
std::for_each(
    gLevelObjects.begin(), gLevelObjects.end(), 
    [&](shared_ptr<Object> obj) 
    { 
     checkpoint.push_back(obj->GetStorable()); 
    }); 
gCheckpoints.push_back(checkpoint); // creates a new checkpoint 

あなたはチェックポイントが復元されたオブジェクトの情報をレンダリング再作成する必要があります。ただし、ほとんどのグラフィックスコンテキストでは、ほとんどの保存システムの要件です。

あなたObjectクラスの設定方法に応じて、あなたはまた、保存されたデータののみで構成されて別のクラスから継承し、単純にそれを保存し、それからrenderablesを作成することができるとき(class RenderObject : StoredObject { ... };)が必要。

オブジェクトをバイナリセーブ、xml、jsonなどの方法でシリアル化し、ファイル(オートセーブ/クイックセーブ/チェックポイント)またはインメモリに格納し、通常の読み込みメカニズムを使用してその特定のファイル。

あなたの計画がどのように設定されているかによってシステムがどのように設定されるかによって、最適な方法が決まりますが、このコンセプトは基本を提供するか、出発点にしてください。

+0

LambdaはC++ 11より前にはサポートされていません。しかし、 'boost.lambda'という解決策があるかもしれません。 – moshbear

+0

@moshbear Lambdasは、それを混乱させることなく、答えに書くのがはるかに簡単です。 ;)11を使用しない場合は、ファンクタで置き換えることができます。 – ssube

+0

書き込みが簡単になりました。 'Boost.bind'はハックのように見えます。 – moshbear

関連する問題