boost::shared_ptr
has an unusual constructor
template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p);
and I am a little puzzled as to what this would be useful for. Basically it shares ownership with r
, but .get()
will return p
. not r.get()
!
This means you can do something like this:
int main() { boost::shared_ptr<int> x(new int); boost::shared_ptr<int> y(x, new int); std::cout << x.get() << std::endl; std::cout << y.get() << std::endl; std::cout << x.use_count() << std::endl; std::cout << y.use_count() << std::endl; }
And you will get this:
0x8c66008 0x8c66030 2 2
Note that the pointers are separate, but they both claim to have a use_count
of 2 (since they share ownership of the same object).
So, the int
owned by x
will exist as long as x
or y
is around. And if I understand the docs correct, the second int
never gets destructed. I've confirmed this with the following test program:
struct T { T() { std::cout << "T()" << std::endl; } ~T() { std::cout << "~T()" << std::endl; } }; int main() { boost::shared_ptr<T> x(new T); boost::shared_ptr<T> y(x, new T); std::cout << x.get() << std::endl; std::cout << y.get() << std::endl; std::cout << x.use_count() << std::endl; std::cout << y.use_count() << std::endl; }
This outputs (as expected):
T() T() 0x96c2008 0x96c2030 2 2 ~T()
So... what is the usefulness of this unusual construct which shares ownership of one pointer, but acts like another pointer (which it does not own) when used.
As a return value, the const in boost::shared_ptr<Bar> const means that you cannot call a non-const function on the returned temporary; if it were for a real pointer (e.g. Bar* const ), it would be completely ignored.
The shared_ptr type is a smart pointer in the C++ standard library that is designed for scenarios in which more than one owner might have to manage the lifetime of the object in memory.
shared_ptr is now part of the C++11 Standard, as std::shared_ptr . Starting with Boost release 1.53, shared_ptr can be used to hold a pointer to a dynamically allocated array. This is accomplished by using an array type ( T[] or T[N] ) as the template parameter.
If you've allocated a shared_ptr dynamically then you're certainly allowed to delete it whenever you want. But if you're asking whether you're allowed to delete whatever object is being managed by the shared_ptr , then the answer is ... it depends.
It is useful when you want to share a class member and an instance of the class is already a shared_ptr, like the following:
struct A { int *B; // managed inside A }; shared_ptr<A> a( new A ); shared_ptr<int> b( a, a->B );
they share the use count and stuff. It is optimization for memory usage.
To expand on leiz's and piotr's answers, this description of shared_ptr<>
'aliasing' is from a WG21 paper, "Improving shared_ptr
for C++0x, Revision 2":
III. Aliasing Support
Advanced users often require the ability to create a
shared_ptr
instancep
that shares ownership with another (master)shared_ptr
q
but points to an object that is not a base of*q
.*p
may be a member or an element of*q
, for example. This section proposes an additional constructor that can be used for this purpose.An interesting side effect of this increase of expressive power is that now the
*_pointer_cast
functions can be implemented in user code. Themake_shared
factory function presented later in this document can also be implemented using only the public interface ofshared_ptr
via the aliasing constructor.Impact:
This feature extends the interface of
shared_ptr
in a backward-compatible way that increases its expressive power and is therefore strongly recommended to be added to the C++0x standard. It introduces no source- and binary compatibility issues.Proposed text:
Add to
shared_ptr
[util.smartptr.shared] the following constructor:template<class Y> shared_ptr( shared_ptr<Y> const & r, T * p );
Add the following to [util.smartptr.shared.const]:
template<class Y> shared_ptr( shared_ptr<Y> const & r, T * p );
Effects: Constructs a
shared_ptr
instance that storesp
and shares ownership withr
.Postconditions:
get() == p && use_count() == r.use_count()
.Throws: nothing.
[Note: To avoid the possibility of a dangling pointer, the user of this constructor must ensure that
p
remains valid at least until the ownership group ofr
is destroyed. --end note.][Note: This constructor allows creation of an empty
shared_ptr
instance with a non-NULL stored pointer. --end note.]
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