Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages
I don't know of any other libraries that provide the functionality of Owned<Container>, but there are several available on the web that provide functionality similar to Owned<T*> and BLink<T>. Those that I am currently aware of are:
- std::auto_ptr, the only smart pointer included with the STL
- boost::shared_ptr with boost::weak_ptr
- boost::scoped_ptr
- arglib smart pointers, part of the arglib library developed by Alan Griffiths
Let's compare them to Owned<T*> and BLink<T>.
The std::auto_ptr has the following characteristics:
- when it is destroyed, it calls delete on the pointer it holds;
- when it is copy constructed or copy assigned, it actually silently transfers the pointer it holds to the new auto_ptr, leaving itself with a null pointer; i.e., a given pointer can only be held by one auto_ptr at a time;
- when its operator-> or operator * are used, they cause the pointer held to be dereferenced;
- you cannot pass an auto_ptr of T to a function expecting a reference to an auto_ptr of const T
MangoPtr::Owned<T*> only does the first of those three:
- when it is destroyed, it calls delete on the pointer it holds;
- copy/assignment:
- a strict Owned cannot be copy constructed or copy assigned; this way, you know exactly when the compiler is calling on those operations, which it otherwise does silently; like a real pointer, your copy constructor must call new() or a cloning method on the return value of operator()
- when a shared Owned is copy constructed or copy assigned, it makes a shallow copy of the pointer value; i.e., a given pointer can be held by several shared Owneds;
- it does not provide a operator-> or operator * because:
- pretending to be a pointer in C++ is clumsy (due to implicit conversions between integers, booleans and pointers mostly, and interaction between "smart" pointers and 'dumb" pointers); instead, you use operator() to get a pointer, thus making explicit the fact that the object is not a pointer but an owner or validatable user;
- it is easy to confuse an operation on the smart pointer with one on the pointee, since . and -> are easily mistaken;
- you can pass an Owned or BLink of T* to a function expecting a reference to one of "T* const"
Boost's shared_ptr has the following characteristics:
- many shared_ptr's can hold the same pointer
- only the last of those shared_ptr's calls delete on the pointer held
- when it is copy constructed or copy assigned, it makes a shallow copy of the pointer value; i.e., a given pointer can be held by several shared Owneds;
- when its operator-> or operator * are used, they cause the pointer held to be dereferenced;
- contrary to std::auto_ptr, it does not require a complete type definition to be known when declared, hence it supports the Pimpl (aka Cheshire Cat) idiom
- it can give its pointer to a weak_ptr
- you cannot pass a shared_ptr of T to a function expecting a reference to one of const T
Boost's weak_ptr has the following characteristics:
- it does not call delete on the pointer held
- when its operator-> or operator * are used, they cause the pointer held to be dereferenced;
- it knows when the last shared_ptr is destroyed (i.e. when the pointer has been delete'd)
- you cannot pass a weak_ptr of T to a function expecting a reference to one of const T
The main idiom recommended for shared_ptr/weak_ptr is to create a shared_ptr for an object allocated from the heap, and create as many shared_ptr's that share that pointer as required (i.e. pass around shared_ptr's). Only create weak_ptr if circular references (common problem with shared ownership if a class A has a shared_ptr to B which has a shared_ptr to A.) can occur. Hope that the weak_ptr does not get dereferenced after the last shared_ptr has been destroyed.
Owned<T*,OStrict> is quite different from shared_ptr:
- only one Owned can own a given pointer
- when it is destroyed, it calls delete on the pointer held
- it does not support copy construction or assignment so that those operations only happen if you really intended them to (ie you tell program how to do the copy, using new or some other method); it also encourages you to use BLink as the main "pass around" object, thereby carrying around only the strict minimum (no ownership).
- it does not provide a operator-> or operator * for the same reasons as mentioned earlier
- does not require a complete type except for constructor;
- it can give its pointer to a BLink<T>
- you can pass an Owned of T* to a function expecting a reference to one of "T* const"
Owned<T*,OShared> is very close to shared_ptr:
- many Owned<T*,OShared>'s can own the same pointer; they can all test for validity in case the pointer was forcibly deleted (via a release)
- only the last of those owners calls delete on the pointer held
- when it is copy constructed or copy assigned, it makes a shallow copy of the pointer value; i.e., a given pointer can be held by several shared Owneds;
- it does not provide a operator-> or operator * for the same reasons as mentioned earlier
- does not require a complete type except for constructor;
- it can give its pointer to a BLink<T>
- you can pass an Owned of T* to a function expecting a reference to one of "T* const"
The BLink<T> has the following characteristics:
- it does not call delete on the pointer held
- it does not provide operator-> or operator *, same reason as for owners
- it knows when the last Owned is destroyed (i.e. when the pointer has been delete'd)
- you can pass a BLink of T to a function expecting a reference to one of const T
The main idiom recommended for Owned/BLink is to create a strict owner for an object allocated from the heap, and pass around as many BLink's that share that pointer as required. Make use of the ability of BLink to validate the pointer held. Always prefer strict ownership over shared ownership: only use shared ownership if it is mandated by your design, or by use of third party library's design (such as the STL, where the containers require shared ownership rather than strict ownership because of problems with overloading std::swap and the multiple copying that takes place during sort operations etc).
Boost's scoped_ptr is a better auto_ptr:
- it does not allow for copy construction/assignment
- it does not require the pointer to be of a complete type
The smart pointers in arglib are described here. Probably the simplest comparison is to extend the table for the Owneds and BLink:
Pointer | Ownership | Copying | Incomplete Types | Const-qualified |
Owned<T*,OStrict> | sole | none | yes | yes |
Owned<T*,OShared> | shared | value | yes | yes |
BLink<T> | none | value | yes | yes |
The "const qualified" is much better in Mango-ptr: it is the same as for pointers. I.e., for pointers you can have the pointer const and the object pointed-to const, and in addition, a function that expects a pointer to const can be given a pointer to non-const. The same is true with both Owned and BLink, something that the arglib pointers cannot do. In fact, the arglib pointers all force constness of the pointee to be the same as that of the pointer, which is rarely a desirable feature.
Generated on Tue Nov 12 20:44:01 2002 for Mango-ptr Library by
1.2.18