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_ptrinstancepthat shares ownership with another (master)shared_ptrqbut points to an object that is not a base of*q.*pmay 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_castfunctions can be implemented in user code. Themake_sharedfactory function presented later in this document can also be implemented using only the public interface ofshared_ptrvia the aliasing constructor.Impact:
This feature extends the interface of
shared_ptrin 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_ptrinstance that storespand 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
premains valid at least until the ownership group ofris destroyed. --end note.][Note: This constructor allows creation of an empty
shared_ptrinstance 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