C++11 带有智能指针std::vector的深度复制构造函数

C++11 带有智能指针std::vector的深度复制构造函数,c++11,stl,smart-pointers,C++11,Stl,Smart Pointers,假设我有一个类FooContainer,它聚合类型为Foo的唯一\u ptr对象 #include <vector> #include <memory> class FooContainer { protected: std::vector<std::unique_ptr<Foo>> many; //other attributes public: FooCoontainer(const FooContainer&); //handlin

假设我有一个类FooContainer,它聚合类型为Foo的唯一\u ptr对象

#include <vector>
#include <memory>

class FooContainer
{
protected:
std::vector<std::unique_ptr<Foo>> many;
//other attributes
public:
FooCoontainer(const FooContainer&);
//handling functions for Foo
};
将尝试复制指针,并且(谢天谢地)编译器将不允许使用unique_ptr。所以我需要这样做

FooContainer::FooContainer(const FooContainer& fc)
{
many.reserve(fc.many.size());
for(int i=0;i<fc.many.size();i++)
many.emplace_back(new Foo(*fc.many[i]));//assume that Foo has a copy constructor
}
FooContainer::FooContainer(const-FooContainer&fc)
{
many.reserve(fc.many.size());
对于(int i=0;i
或者我应该使用共享的而不是唯一的

这取决于您是需要深度拷贝,还是可以使用浅拷贝(这意味着对其中一个拷贝的更改也将在另一个拷贝中可见)

但是,.BarContainer的复制构造函数有问题。它将调用FooContainer的复制构造函数,该构造函数将过时并仅复制Foo部分而不是整个Bar

通常的解决方法是为基类提供一个虚拟方法
clone

class Foo {
public:
    Foo(Foo&&) = default;
    Foo& operator=(Foo&&) = default;
    virtual ~Foo() = 0;
    virtual std::unique_ptr<Foo> clone() const = 0;

protected: // or public if appropriate
    Foo(const Foo&);
    Foo& operator=(const Foo&);
};

class Bar : public Foo {
public:
    virtual std::unique_ptr<Foo> clone() const;
};

std::unique_ptr<Foo> Bar::clone() const {
    return make_unique<Bar>(*this);
}
我使用了一个模板函数
make_unique
,该函数被意外地从C++11标准中遗忘,但很快将正式发布。如果您的编译器没有模板函数,可以将自己的模板函数放在一些头文件中:

template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&& ... args) {
    return std::unique_ptr<T>( new T(std::forward<Args>(args)...) );
}
模板
std::unique_ptr使_唯一(Args&&…Args){
返回std::unique_ptr(新的T(std::forward(args)…);
}

(加在一起,
unique\u ptr
make\u unique
shared\u ptr
make\u shared
,和
vector
完成了巨大的语言改进,这意味着你几乎不再需要低级危险的
新的
删除
关键字。)

你可能想要一个虚拟的
克隆()
Foo
及其子类中的
成员函数,它可以返回一个由
*此
构造的
唯一\u ptr
副本。感谢您的回答是的,我确实需要一个深度副本。我也有点难以理解什么
返回std::make\u unique(*此)
是的。它看起来像是返回了实际应该是的对象的唯一的\u ptrcopied@AndreyPro:想一想:给定一个
T*p
,你怎么可能复制一个最派生的对象,其中
*p
是一个子对象?没有一般的答案。据我所知,make_unique将调用copy construct然后返回副本的唯一ptr?我想我需要使用push_-back而不是emplace_-back
FooContainer::FooContainer(const FooContainer& fc)
{
    many.reserve(fc.many.size());
    for (auto const& fptr : fc.many)
        many.emplace_back(fptr->clone());
}
template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&& ... args) {
    return std::unique_ptr<T>( new T(std::forward<Args>(args)...) );
}