1

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?

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • "the new vector there should be pointers to the same polymorphic types just not pointing to the same data" - They have to point to *something*. Do you want to *copy* the objects or just the pointers? – WhozCraig Sep 23 '13 at 22:04
  • 5
    You'd have to make your `Component` objects [cloneable](http://stackoverflow.com/a/5148751/10077). – Fred Larson Sep 23 '13 at 22:04
  • 2
    I would suggest smart pointers, not raw pointers. – chris Sep 23 '13 at 22:05
  • I want to copy the values that are pointed to in the vector and point to them in another vector and different position on the heap – Brendan Webster Sep 23 '13 at 22:06
  • never heard of cloning before, I'm relatively new to major use of polymorphic ideas, add that as an answer and I'll accept it – Brendan Webster Sep 23 '13 at 22:08

2 Answers2

3

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;
}
Manu343726
  • 13,969
  • 4
  • 40
  • 75
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());
  }
}
Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132