Re: ANN: AutoNewPtr (oh yes, yet another smartpointer)
* Roland Pibinger:
On Sun, 11 May 2008 20:13:18 CST, "Alf P. Steinbach" wrote:
I just coded this up, and hopefully by mentioning it here I'll get
some useful feedback, like, bugs, shortcomings, improvements...
http://code.google.com/p/alfps/source/browse/trunk/alfs/pointers/AutoNewPtr.
hpp
(http://preview.tinyurl.com/3puorr)
Disclaimer: Haven't looked into all the intricacy of the code in
detail.
AutoNewPtr ("new" Berkeley open source license)
* Is not initialized with a raw pointer, but with constructor
arguments for the to-be referent: AutoNewPtr takes responsibility
for 'new'.
AFAICS, you need to support const and non-const arguments.
Well, if conventional, straightforward notation is to be supported
then until C++0x that leads to a combinatorial explosion, e.g. 63 =
2^(5+1)-1 constructor overloads for support for 5 or fewer arguments,
and it's very rare that a non-const constructor argument makes sense.
The only case I'm aware of where such support could be beneficial is
for the ability to pass an rvalue of type T where T does not have a
T(T const&) copy constructor, e.g. rvalue of std::auto_ptr<U>.
So this is a limitation of the trade-off chosen: it doesn't support
actual constructor arguments that are rvalues of types like
std::auto_ptr (however, such types are exceeedingly rare). Although I
didn't think of this particular problem, the general problem of
std::auto_ptr quirks was part of the reason why I experimented with
adapations of unique_ptr and move_ptr. That code's still there.
* By doing that, it has the ability to add a notifier to the created
object, so that the smart pointer gets notified when referred
object self-destructs, if it does (e.g., a window or file closing,
or a non-correctable error).
Why? You are the owner/creator of the object. Self-destruction seems
to contradict the main point of the design.
Supporting the possibility self-destruction, or other early
destruction via an agency that is not the smart-pointer, is the main
point of CheckingPtr, which AutoNewPtr builds on. For example,
objects that represent GUI objects often self-destruct. That means
that e.g. shared_ptr is ungood for such objects. AutoNewPtr takes the
support for self-destruction one step further than CheckingPtr. While
CheckingPtr requires that T derives from a special notifier class (a
destruction event source) in order to be able to detect pointee
destruction, AutoNewPtr adds such derivation automatically it if isn't
there already, so that client code doesn't need to address this.
The usual solution for self-destructing API objects is instead to let
the C++ wrapper object enter a zombie state when the underlying (e.g.)
GUI objects self-destructs. With AutoNewPtr or CheckingPtr, one can
let the C++ wrapper also destruct. That means that it does not need
to support a zombie state, which simplifies its implementation, and
that the client code does not need to very much check for zombieness,
because that's now automated via the smart pointer.
As another example, objects that represent e.g. files often enter a
zombie state (std::istream and std::ostream objects do). The
implementation of such objects, and use of them, can be very much
simplified, and thus be more reliable, if instead of going to a zombie
state, the object simply self-destructs, so that the statement "if the
object exists, then it's valid and useable" is always true. Then, the
error state, or rather, now, non-existence, is automatically detected
by AutoNewPtr or CheckingPtr, and can be checked by client code.
So, essentially, this isn't about self-destruction as such, but
support for avoiding zombie states in the cases where the problem
domain imposes self-destruction (like GUI) or where the problem domain
imposes zombie states (like files, network connections, ...).
But as mentioned, this code is more like exploration of an idea or
sets of ideas, than something final. In particular there is the
theoretical problem of objects that, imposed by the problem domain,
/always/ self-destruct and are /never/ explicitly destroyed, like e.g.
a button widget in a window, with some GUI API that doesn't support
explicit destruction. With e.g. AutoNewPtr the wrapping C++ object is
automatically destroyed (although that destruction is customizable)
when there are no more smart pointers to the object; however, the C++
wrapper can simply choose to not destroy the object that it wraps.
* After referred object destroyed, pointer reports that it's void
and throws on access via ->.
Ok
* Also, the default constructor sets the pointer to void state.
Hmm, a semantic anomaly.
Yes, I agree. As a concrete example that e.g. std::swap (I'm just
using it as an example, std::swap can be easily customized so
std::swap itself is not a problem) does
T temp( a ); a = b; b = temp;
and if such code is just a little bit less clever,
T temp;
temp = a; a = b; b = temp;
then a default constructor that new'ed would be less than perfect...
Ditto for creating arrays, so
AutoNewPtr p; // Like p = 0
Where you want a default-constructed pointee, the AutoNewPtr notation
is therefore to say that explicitly,
AutoNewPtr<T> p( newNoArgs ); // Like p = new T;
* Otherwise much like shared_ptr, except customization of deleter is
per type (via c++0x-like std::default_delete) rather than per
instance.
So it's a SharedNewPtr rather than a AutoNewPtr. I fail to see where
you can configure a deleter in 'template<typename T> class
AutoNewPtr'.
The deleter customization ability is the to-be-standard
std::default_delete mechanism, illustrated in the test code.
Moreover, the main point of the design seems to be that
construction and destruction happen inside AutoNewPtr which
contradicts the customization of a deleter.
Well, that customization ability is there for free, simply by using
std::default_delete instead of directly delete. :-)
Cheers, and thanks for your comments,
- Alf
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]