Assume we have two classes A
and B
. By design, A
’s object will be dynamically allocated through make_unique.
The class B
will be one of the class member of A
. should I use std::unique_ptr
of B
in A
or just define a normal variable of B
in A
?
class B {};
class A {
A(std::uniqur_ptr<B> b_ptr) : b_(move(b_ptr)) {}
private:
std::unique_ptr<B> b_;
};
or
class B {};
class A {
A(const B& b) : b_(b) {}
private:
B b_;
};
just want to know the difference of above snippets.
As @eerorika said, storing it directly as a member variable is often a better default to go to.
std::unique_ptr
is used to denote unique ownership (e.g. the class using this "owns" the memory at that location) -- but ordinarily this is only used when necessary for technical reasons. To name a few such technical reasons:
You need polymorphic behavior, but also need your class to own the object. In such a case, you would be using a std::unique_ptr<Base>
to use virtual-dispatch to call functions from the underlying Derived
instances. You can't store a value of type Base
and get polymorphic behavior, so it has to be done indirectly by either a reference or a pointer. std::unique_ptr
makes this possible while conveying the ownership semantics.
You have a class that is extremely large, or costly to copy/move. For example, if you have a data member of std::array<int,100000>
-- you may not want to have to copy that around directly. However, a std::unique_ptr
will instead use indirection while allowing for the object to be constructed once and passed in (no penalty for copying)
You have a class that is uncopyable and immovable, but you would like to make the owning class copy or movable. For example, you may have a std::mutex
internally -- but you may want to permit moving. In such a case you may have either std::unique_ptr<std::mutex>
or, better yet, an internal struct
held by a unique_ptr
so that moving is a cheap and easy operation (since now it only moves pointers).
You need the data to outlive the class. Dynamic lifetimes allow lifetimes that are irrespective of scopes, and in some cases, this can be necessary if you want the inner workings of a class to be kept alive outside the normal scope of that class.
There are plenty of reasons where a std::unique_ptr
is the "right" choice, but these are the most common ones that come to mind. There is also std::shared_ptr
/std::weak_ptr
used for sharing, which has similar justifications to above, but matters when ownership needs to be distributed across multiple objects.
In either case, the determination always comes down to the technical reasons/requirements for your class. In your minimal example, class B{}
is empty, so it doesn't make sense to use std::unique_ptr
here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With