Re: Making a smart pointer which works with incomplete types
Alf P. Steinbach wrote:
* Juha Nieminen:
Alf P. Steinbach wrote:
You mean, by explaining things carefully, and even posting working code?
The first code you posted didn't work
I beg your pardon, it worked very nicely. I posted tested code to you.
You posted a smart pointer which only works for incomplete types if
the user provides the smart pointer class with a pointer to a deleter
function, and then you wrote an example of how to use it like that.
However, your code does not work for incomplete types if the user does
not give it the deleter function. Thus it doesn't work for all cases.
because it required the type to be complete at destruction.
It did not have such requirement.
In your original code you directly called the templated deleter
function from the destructor of the smart pointer. That instantiates the
deleter function in the context where the destructor is called and thus
requires for the type to be complete.
Perhaps you managed to misunderstand it.
I understood that in order to work with incomplete types the user has
to give it a deleter function. Too burdensome and unnecessary.
Note that in all codes so far, including your own, there has been a
function that does the destruction, at a point where the type is
complete; I'm assuming that is not what you're referring to, since that
would be a fallacy.
The difference is whether the type must be complete when the
destructor (or assignment operator) of the smart pointer is executed or
not. The destructor must not instantiate the deleter function (because
if it does so, it immediately requires for the type to be complete). The
only way to avoid that is to call the deleter function indirectly
through a pointer.
The second code might work but is unnecessarily complicated to use.
There's no need for such complication.
It's dead easy to use, but it's not as good a solution as the first.
Both of your solutions are worse than the one used by
boost::shared_ptr and my variant because both of your solutions require
additional things from the user which eg. boost::shared_ptr doesn't.
It's automatic, it's easy to use, it works
with incomplete types and it doesn't increment the size of the smart
pointer class. Exactly what is "absurd" there?
I don't know what you think is absurd, but the static pointer in there
is, as I wrote earlier, nonsensical. A very dirty trick to make the
client code less explicit, and less maintainable (think about replacing
your smart pointer class with something more general or just different),
and less thread-safe, in a very rare case.
Of course it makes the user code less explicit. That's the whole point
of abstraction. Ever heard of such a thing? Abstraction adds to the
maintainability and reusability of the code, not the other way around.
As for thread-safety, your solutions are in no way better. The user
manually providing a deleter function does not make it any more thread-safe.
Besides, all your complaints apply directly to boost::shared_ptr
because it uses THAT EXACT SAME MECHANISM as I did in my original post.
For some reason you don't seem to get this simple fact.
All in order to avoid 1 line of client code in that rare case.
Why require any additional lines for no good reason? boost::shared_ptr
doesn't require any such additional lines, and it works with incomplete
types just fine.
You are simply struggling around the problem of admitting, that
perhaps it's not as "absurd" after all.
From my point of view it is a dirty hack.
Used by boost::shared_ptr.
But it wasn't your hack. You
asked how to avoid it
Excuse me? Where exactly did I ask this?
What I asked was whether the function pointer member variable could be
made static or not.
and I've shown you some ways
Which only make the usage of the smart pointer more complicated with
no benefit whatsoever.
, and instead of
whining and worrying (but I notice that that wasn't until after an
anonymous attack, don't let those trolls influence you) I'd expect
thanks for giving you solutions to stated prob.
I'd give thanks if your solutions worked, but they don't. They just
make the usage of the class more complicated for no reason.