Let\'s say I have a class FooContainer that aggregates unique_ptr objects of type Foo
#include
#include
class FooContainer
{
p
Or may be I should use shared_ptr instead of unique_ptr?
That depends on whether you require deep copies or are okay with shallow copies (meaning changes to one will also be visible in the other).
However,. the copy constructor of the BarContainer is problematic. It will the call copy constructor of FooContainer, that will go agead and copy only the Foo part instead of whole Bar.
The usual fix is to give your base class a virtual method 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);
}
If Foo
is not abstract, it would also have an actual implementation of clone()
.
FooContainer::FooContainer(const FooContainer& fc)
{
many.reserve(fc.many.size());
for (auto const& fptr : fc.many)
many.emplace_back(fptr->clone());
}
I've used a template function make_unique
, which was accidentally forgotten from the C++11 Standard, but will be official soon. If your compiler doesn't have one, it's simple to put your own in some header file:
template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&& ... args) {
return std::unique_ptr<T>( new T(std::forward<Args>(args)...) );
}
(Together, unique_ptr
, make_unique
, shared_ptr
, make_shared
, and vector
finish the huge language improvement meaning you'll almost never need the low-level and dangerous new
or delete
keywords again.)