Boost logo

Boost :

From: Bronek Kozicki (brok_at_[hidden])
Date: 2004-01-18 14:52:25


Jonathan Turkanis <technews_at_[hidden]> wrote:
>
> The implementation of auto_ptr seems impressive! I have not
> studied it in detail, but it looks like it correctly handles the four
> cases in
> http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/1997/N1128.pdf.

Credit goes to Rani Sharoni :)

> With something as subtle as auto_ptr, you defintely need to
> provide a test program to prove that it satisfies the various auto_ptr
> desiderata. The only one I know of is here:
> http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2000/n1232.pdf.
> This test fails to compile (on VC7.1) with your auto_ptr; this doesn't

My fault, fixed in version 0.71 (available at YahooGroups and here:
http://b.kozicki.pl/cpp/ext_auto_ptr_071.zip ) . It contains T191.hpp
(fixed auto_ptr), T192.cpp (more samples with comments), T193.cpp (test
program from N1232). Thanks for your attention!

Now explanation of deleter concept as defined in auto_ptr : deleter is
called from trampoline template function, which is defined at the point
of auto_ptr initialization. Cost of to this function is very small (just
2 pointers more, no CPU overhead, no extra dynamic allocations) and this
is biggest advantage over shared_ptr. Biggest improvement over
std::auto_ptr is point of definition of this deleter. In std::auto_ptr
it's in (real or potential) destruction point of std::auto_ptr, while in
proposed auto_ptr it's point of auto_ptr initialization with raw
pointer. This brings few interesting new applications:

* you no longer need to make your class polymorphic in order to call
right destructor at the point of auto_ptr destuction, like in following
example:
  struct Base{};
  struct Derived : public Base {};
  auto_ptr<Base> p = auto_ptr<Base> (new Derived);
  // which destructor gets called when p goes out of scope ?

* when passing ownership, new owner does not need access to deletion
functionality. At the point of destruction of new owner, this deletion
function might be:

* not accessible (like private function of some class), or ...

* not defined in translation unit, or ...

* conflicting - which may happen when few independent libraries are
linked with static runtime library, and you need to pass auto_ptr
between them. You have warranty that "delete" will release memory in
context of the very same copy of static runtime, which created managed
object - even when last owner has it's own copy of runtime!

* new owner does not need to know how to release owned object; it may
even receive array instead of single pointer, and it still will be
properly deleted (but I agree that this particular example is not really
impressive)

* full support for incomplete types. Deletion of object must be only
defined at the point of auto_ptr initialization with raw pointer.
Default constructor will actually call "delete 0;" in deletion
function, which is safe even if deleting pointer to incomplete type.

* limited support for functor deleters (ie. deleters as defined for
shared_ptr). At the end of T192.cpp you will find example of how such
deleters might be used.

You will need improved auto_ptr in any situation when you actually need
smart pointer with strong ownership semantics (like std::auto_ptr), but
for some reason std::auto_ptr is not good enough. These situations
include:

* unsual deletion of owned pointer (see "Strange" class in T192.cpp)

* you need to execute some additional code when owned pointer gets
released

* you need to manage lifetime of incomplete class (see "Incompl" class
in T192.cpp)

* you do not want to make class polymorphic in order to have
well-defined behaviour at the point of object destruction, but you need
to pass ownership to auto_ptr<Base>

* you want to pass auto_ptr between parts of program, or even
independent libraries, but not all potential owners have access to
deletion functionality needed to properly release owned pointer.

Currently under any of these circumstances you would use shared_ptr.
While being more versatile than auto_ptr, it brings more overhead (extra
dynamic allocation) and does not deliver strong ownership semantics.

B.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk