Скопируйте вектор указателей без нарезки

Мне нужно скопировать вектор полиморфных объектов, в новом векторе должны быть указатели на те же полиморфные типы, просто не указывающие на одни и те же данные, а вместо этого они должны указывать на новые данные в куче. Эти данные должны быть установлены на те же данные, что и исходный вектор.

пример

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

в этом случае новая векторная сущность просто получает указатели от baseEntity. Слайсинг здесь не происходит, но когда я меняю указатель в baseEntity, он также меняет данные в сущности. Как мне правильно скопировать его для моей ситуации?

1

Решение

Вот пример клонирования:

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

Другие решения

Чтобы достичь этого, вы должны предоставить метод для клонирования объектов полиморфным способом, то есть предоставляющий переопределяемую функцию клонирования:

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

Теперь при копировании вектора переместите его, вызывая метод clone каждого элемента:

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

По вопросам рекламы [email protected]