Question

I need to copy a vector of polymorphic objects, in the new vector there should be pointers to the same polymorphic types just not pointing to the same data, but instead they should point to new data on the heap. That data needs to be set to the same data as the original vector.

Example

std::vector < Component * > entity = baseEntity;

in this case the new vector entity just gets the pointers from baseEntity. Slicing doesn't occur here, but when I change the pointer in baseEntity it also changes the data in entity. How do I copy it correctly for my situation?

Was it helpful?

Solution 2

Here's an example of cloning:

#include <memory>
#include <vector>

struct Component {
  virtual std::unique_ptr<Component> clone() const = 0;
};

struct AComponent : Component {
  virtual std::unique_ptr<Component> clone() const
  {
    return std::unique_ptr<Component>(new AComponent(*this));
  }
};

struct BComponent : Component {
  virtual std::unique_ptr<Component> clone() const
  {
    return std::unique_ptr<Component>(new BComponent(*this));
  }
};

int main(int,char**)
{
  std::vector<std::unique_ptr<Component>> old_entities;
  old_entities.push_back(std::unique_ptr<Component>(new AComponent));
  old_entities.push_back(std::unique_ptr<Component>(new BComponent));
  std::vector<std::unique_ptr<Component>> new_entities;
  new_entities.reserve(old_entities.size());
  for (auto &entity : old_entities) {
    new_entities.push_back(entity->clone());
  }
}

OTHER TIPS

To achieve that you have to provide a method to clone objects in a polymorphic way, that is, providing a overridable cloning function:

class Base
{
public:
    virtual std::unique_ptr<Base> clone() = 0;
};

class Foo : public Base
{
    int _class_stuff;

public:
    virtual std::unique_ptr<Base> clone()
    {
        return std::unique_ptr(new Foo(*this)); //Calls copy ctor
    }
};

Now when copying the vector, trasverse it calling the clone method of each element:

std::vector<std::unique_ptr<Base>> clone_vector(const std::vector<std::unique_ptr<Base>>& vector)
{
    std::vector<std::unique_ptr<Base>> result;

    for(auto& element : vector)
        result.push_back(element->clone());

    return result;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top