简体   繁体   English

C ++:完整复制指针向量

[英]C++: make full copy of vector of pointers

I'm working on a C++ game. 我正在开发C ++游戏。 My level objects are in a vector (Object being a superclass for my level's objects). 我的关卡对象在矢量中(对象是我的关卡对象的超类)。

I need the state of this vector to be saved at checkpoints, and retrieved at death. 我需要将此向量的状态保存在检查点,并在死亡时检索。

So at the beginning of the level, the vector (objects) is created (old_objects). 因此,在关卡开始时,将创建矢量(对象)(old_objects)。

If you hit a checkpoint, old_objects is erased and objects is re-copied to old_objects. 如果单击检查点,则将清除old_objects,然后将对象重新复制到old_objects。

If you die, the data from objects is erased and old_objects is copied back to objects. 如果死了,则来自对象的数据将被擦除,并将old_objects复制回对象。

I've been trying to do this several ways but I'm not able to get it working. 我一直在尝试几种方法来执行此操作,但无法使其正常工作。 Help? 救命?

EDIT: I tried using a virtual clone() method. 编辑:我尝试使用虚拟clone()方法。 It throws out of range errors. 它抛出超出范围的错误。

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());
}

But all I get is the same old: 但是我得到的都是一样的老:

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.

You could use the Prototype pattern and have your Object base class declare a pure virtual clone() method. 您可以使用Prototype模式,并让您的Object基类声明一个纯虚拟的clone()方法。 Then at checkpoint time you just have to iterate over the vector calling clone on the pointers and pushing them into the new vector. 然后在检查点时间,您只需要遍历向量,然后在指针上调用clone并将其推入新向量。

The only important requirement here is to provide a deep copy constructor that stores all necessary information (or if that's not possible, a method to get all the required info). 这里唯一重要的要求是提供一个深层复制构造函数,该构造函数存储所有必需的信息(或者,如果不可能的话,该方法将获取所有必需的信息)。 Then use that ctor/method to create a second vector. 然后使用该ctor /方法创建第二个向量。 Something like: 就像是:

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);
    }
};

then to store "checkpoints", you simply do: 然后存储“检查点”,您只需执行以下操作:

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

You will need to recreate the render information for the objects when the checkpoint is restored; 还原检查点后,您将需要为对象重新创建渲染信息。 this is a requirement for most save systems in most graphics contexts, however. 但是,这是大多数图形环境中大多数保存系统的要求。

Depending on how your Object class is set up, you can also inherit from another class that consists only of the stored data, and simply store that and create the renderables from it when necessary ( class RenderObject : StoredObject { ... }; ). 根据Object类的设置方式,您还可以从包含已存储数据的另一个类继承,并简单地存储该数据并在必要时根据该数据创建可渲染对象( class RenderObject : StoredObject { ... }; )。

You can alternatively serialize the objects in some fashion (binary save, xml, json) and store that to a file (autosave/quicksave/checkpoint) or in-memory, and then use your regular loading mechanism to load that specific file. 您也可以以某种方式(二进制保存,xml,json)序列化对象并将其存储到文件(自动保存/快速保存/检查点)或内存中,然后使用常规的加载机制加载该特定文件。

The best method depends on what your plans are and how your system is set up, but this concept should provide the basics or give you a starting point. 最佳方法取决于您的计划和系统设置,但是此概念应提供基础知识或为您提供一个起点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM