基类的vector
shared_ptr
。
struct Base
{
virtual ~Base() = 0 {}
};
struct Derived1 : Base
{
};
struct Derived2 : Base
{
};
std::vector<std::shared_ptr<Base>> v;
v.push_back(std::make_shared<Base>(Derived1()));
v.push_back(std::make_shared<Base>(Derived2()));
如何制作vector
的副本?
副本的指针必须指向新对象。
答案 0 :(得分:2)
您想要shared_ptr集合的深层副本吗?
我只会参考以下文章。
Deep copy constructor with std::vector of smart pointers
这是我刚写的代码。
#include <string>
#include <memory>
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
using namespace std;
class Parent {
string _name;
public:
virtual shared_ptr<Parent> clone() const = 0;
Parent(const string& name) { _name = name; }
string getName() { return _name; }
void setName(const string& name) { _name = name; }
};
class Child : public Parent {
public:
Child(const string& name) : Parent(name) {}
virtual shared_ptr<Parent> clone() const { return make_shared<Child>(*this); }
};
int main()
{
vector<shared_ptr<Parent>> origins =
{
shared_ptr<Parent>(new Child("ant")),
shared_ptr<Parent>(new Child("bee")),
shared_ptr<Parent>(new Child("cat")),
};
vector<shared_ptr<Parent>> clones;
// copy origins to clones
transform(
origins.begin(),
origins.end(),
back_inserter(clones),
[](const shared_ptr<Parent>& ptr) -> shared_ptr<Parent> { return ptr->clone(); }
);
// modify values of origins
for (const auto& origin : origins) { origin->setName(origin->getName() + "!"); }
// print origins (modified)
cout << "<origins>" << endl;
for (const auto& origin : origins) { cout << origin->getName() << endl; }
// print clones (not modified)
cout << "<clones>" << endl;
for (const auto& clone : clones) { cout << clone->getName() << endl; }
return 0;
}
答案 1 :(得分:2)
您应该向virtual
添加纯clone
成员函数,例如Base
。在派生的class
es中实现它,然后执行以下操作:
std::vector<std::shared_ptr<Base>> copy(std::shared_ptr<Base> const &input) {
std::vector<std::shared_ptr<Base>> ret;
ret.reserve(input.size());
for(auto const &p: input) {
ret.push_back(p->clone());
}
return ret;
}
话虽如此,这是一个坏主意。您正在打破语义,例如直接分配vector
和复制构造函数,因为它们不会执行用户期望的操作(假设您实际上需要实际创建每个对象的新实例)。
答案 2 :(得分:0)
只需复制即可。
auto v2 = v;
容器保存共享指针,因此它们在复制后会很好,并且仍然指向相同的对象,同时保持它们的活动状态。这里没问题。