我有一个std::vector<std::unique_ptr<BaseType>>
。有什么干净的方法可以制作vector
的深层副本吗?
我唯一想到的就是拥有一个使用dynamic_cast
来检索派生类型,然后将其复制到unique_ptr
所拥有的新对象中的函数。鉴于我可以控制所有可能的派生类,因此这是可行的。这有各种明显的缺点。
以前,我曾经使用过一个类,它是所有派生类型的并集。在尝试摆脱这种情况时,我遇到了需要复制vector
的情况。
这个问题有什么好的解决方法吗?我唯一能想到的解决方案是丑陋的,甚至让我感到羞耻。这是尝试重构/清理我使用的代码的一大步。
vector
是必须可复制的类的成员。因此,在这种情况下,我只需要确保可以为包含的类编写一个副本构造函数即可。
答案 0 :(得分:1)
最简单的方法是实施某种形式的克隆,然后使用std::transform
:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <memory>
#include <vector>
struct base {
// For constructors and destructors, it's business as usual.
// Remember to implement the rule of five.
base() {std::cout << "new base\n";}
base(const base& o) {
std::cout << "copied base\n";
}
virtual ~base() {std::cout << "destructed base\n";}
// This is the virtual copy function. We need this because only
// the actual derived class will know how to copy itself. The
// only way to forward this knowledge to a pointer to the base
// class is via a virtual function.
// You can make this pure virtual, if you don't mind
// the base being abstract (or if you *want* to make it
// abstract). It'll be safer this way.
virtual base* copy() {return new base(*this);}
};
struct derived : base {
derived() : base() {std::cout << "new derived";}
derived(const derived& o) : base(o) {
std::cout << "copied derived\n";
}
virtual ~derived() {std::cout << "destructed derived\n";}
base* copy() override {return new derived(*this);}
};
// example of deep copying
int main() {
std::vector<std::unique_ptr<base>> v;
v.emplace_back(new base());
v.emplace_back(new derived());
std::vector<std::unique_ptr<base>> copy_of_v;
// The transformation merely calls copy(). Each object will be copied into
// an instance of the correct type.
std::transform(v.begin(), v.end(), std::back_inserter(copy_of_v), [](auto& item){
return std::unique_ptr<base>(item->copy());
});
}