Re: which pointer
Nick Keighley <nick_keighley_nospam@hotmail.com> wrote in news:81377349-
fdb9-4d2f-9852-c2b2a3bc1a3f@j14g2000yqm.googlegroups.com:
I wanted my code to look something like this
void new_call (Msg& msg)
{
smart_ptr<Call> call_ptr ();
CallList::add (*call_ptr); // may throw
Call *call = call.release();
call.process_msg (msg);
}
now that may not be quite right, but the aim was to allocate a Call
and store it in CallList. If CallList throws the smart_ptr will
destroy the Call, otherwise process the message and the call remains
in the CallList for more message processing.
smart_ptr would not allow copy or assignment. Release returns the
pointer value and zeros its record. I was going to call it
ExplicitReleasePointer. But then I thought,surely boost have already
done this. Aha! scoped_ptr! Oops no. No release(). The rationale for
this is that scoped_ptr implies no transfer of ownership. But I want
to transfer ownership. That I should use auto_ptr if I want transfer
of ownership semantics. But how do I coerce auto_ptr into doing the
cleanup. Should I be making my container class do the cleanup? Or
should I be using shared_ptr in both the container class and my
calling function?
If I understand correctly, then you want something like ScopeGuard (look
it up):
#include <ScopeGuard/ScopeGuard.h>
template <class T> struct Delete {
void operator()(T *t) const { delete t;}
};
void new_call (Msg& msg)
{
Call* call_ptr = new Call();
// assume ownership
ScopeGuard guard = MakeGuard( Delete<Call>(), call_ptr);
// pass object to container, container will assume
// ownership iff the call does not throw.
CallList::add(call_ptr); // may throw
// give up my ownership
guard.Dismiss();
// call a method on the object owned by the container
call_ptr->process_msg (msg);
}
I suppose the logic is that ownership is shared so you need a shared
pointer.
Yes, a cleaner way would be to use boost::shared_ptr both in the
container and in the caller function.
hth
Paavo