Re: setter for deleter in boost::shared_ptr (and alike)
* James Dennett:
Alf P. Steinbach -> Alberto Ganesh Barbati:
OK. So when you wrote
It's true that with the pointer returned by get_deleter() you can call
non-const functions on the deleter, however you still can't replace it
with another (possibly unrelated) deleter and that's the important
thing, IMHO.
you didn't mean that one
"can't replace it with another (possibly unrelated) deleter",
as you literally wrote, but you meant that one
"can't replace it with another deleter of a different static type",
just like given int* p, you can't change the type of int to double by
assigning a double value to *p.
I think he meant that one
"can't replace it with another deleter"
because you can't replace it at all, you can only change properties
of the existing deleter. Its identity will be unchanged. It's true
that you can't replace it by an object of a different type, but that
is a trivial corollary of the fact that you can't replace it by a
different object at all.
Ah, well, what notion is implies the other is just a matter of throwing
dice or the moon's phase, or something, as I see it. ;-)
Anyway, now we got that terminological thing cleared up, the design
choices discussed so far can be summarized in terms of three actors: the
shared_ptr code, the instantiating code, and other code.
1. shared_ptr can allow setting a deleter of any (callable) type, at
any time. The instantiating code can then not place constraints
on other code's replacements of the deleter. Other code can freely
change the effect of shared_ptr's deleter invocation.
2. shared_ptr (what it actually does) can allow assigning a deleter of
the same type as specified at instantiation. The instantiating
code has full control because it can choose a non-assignable type.
If that control is not exercised, however, other code can freely
change the effect of shared_ptr's deleter invocation.
3. shared_ptr can disallow changing the deleter (except in certain
very limited ways such as a "release" operation).
I've characterized option 1 as irrelevant because it voids the
destruction guarantee that shared_ptr is all about; it would be like a
dangerous high-voltage installation that's designed to be utterly safe
for anyone not entering, but with an unlockable, always wide open door.
Option 2 has a lockable door, but it takes some effort for the
instantiating code to actually lock the door. And the simplest and I
gather to many the most natural way of using shared_ptr's custom
deleter, a function pointer as deleter, doesn't lock the door.
I think the reason that this design, a door that's open by default but
/can/ be locked, the reason it doesn't seem very bad to everybody is
simply that what's inside that particular door is not very interesting
to high-voltage installation experts: not being able to imagine any
reason that anyone would try to enter, it's so dull the whole thing,
well, with nobody there it isn't dangerous at all, and anyway, an expert
will always take that extra effort to lock the door, just of out habit.
But consider: if access to those uninteresting innards of the facility
is truly required in some situations, then that door could just as
easily be locked /by default/, a snap-lock, so that instead of extra
effort to lock it, the instantiating or other code would have to do some
extra thing in order to unlock it for other code or itself. For
example, the operation to replace or change (whatever) the deleter could
require the deleter to be of class type convertible to
"replacable_deleter", in which case the instantiating code would still
have full control, but now a by default locked door. Or, less draconian
and perhaps more practical, security-by-obscurity, the operation to
unlock could require supplying an object implementing "replace_deleter",
which could be made not-completely-trivial to implement, so that other
code wouldn't do that by accident, some spur of the moment idea.
If the intent truly was to provide possible access to the innards, then
the snap-to lock, the door that's locked by default instead of wide open
by default, e.g. implemented as suggested above, would be my choice.
But my personal preference is option (3), essentially no change allowed.
Cheers,
- 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! ]