|
Boost : |
From: Vugts, Robert (robert.vugts_at_[hidden])
Date: 2000-12-21 17:51:10
Looking at the ugly changes required to implement the release method
(which is only going to be of use in rare cases) I don't think adding
the release method is justified. It just isn't the right operation
on a reference counted pointer. I'm also not happy with the extra
processing going on just in case somebody may want to use the release
method. (I'm a big fan of the "you don't pay for what you don't use"-
principle).
Wouldn't it be better to implement the release method in such a way
that it returns a cloned pointer if the use-count > 1 ?
Rob Vugts
-----Original Message-----
From: Gary Powell [mailto:Gary.Powell_at_[hidden]]
Sent: 21 December 2000 18:37
To: 'boost_at_[hidden]'
Subject: RE: [boost] Suggestion: scoped_ptr::release()
> What is the release method supposed to do when the use-count > 1 ?
>
I may take back my support for adding release() if a whole host of
complications keep arising, but for now I would want the following to occur:
If the method is shared, then you can't decrement the count. Otherwise, when
other use of the shared_ptr goes out of scope it will delete the data. Thus
invalidating the object holding the non counted pointer.
template<typename T>
T *shared_ptr<T>::release()
{
if (use_count() > 1)
return px;
T *rtn = px;
px = 0;
return rtn;
}
Of course now more code changes
template<typename T>
void shared_ptr<T>::dispose()
{
// must check that px exists.
if (--*pn == 0) { if (px) delete px; delete pn; }
}
We could also delete pn at the time of call to release() but then a whole
host of other things won't work, like operator=(); As it is, operator*(),
will have undefined behaviour ( likely crash) if called on an shared_ptr<>
for which release() has been called. (That's ok behaviour for me.)
This of course leaks the pointer to the count (pn) This could be fixed by
making the counter negative which would indicate that the base pointer isn't
to be deleted. (This is getting ugly..)
template<typename T>
T *shared_ptr<T>::release()
{
if (*pn > 0)
{
*pn = -*pn; // reverse sign
}
decrement();
return px;
}
Of course now even more code changes Plus new fns are needed.
template<typename T>
void decrement()
{
if (*pn > 0)
--*pn;
else
++*pn;
}
template<typename T>
void increment()
{
if (*pn > 0)
++*pn;
else
--*pn;
}
// replace all ++*pn and --*pn with calls to increment() and decrement()
template<typename T>
long shared_ptr<T>::use_count() const
{
return abs(*pn);
}
template<typename T>
void shared_ptr<T>::dispose()
{
if (*pn > 1)
{
if (--*pn == 0 ) { delete px; delete pn; }
}
else
{
if (++*pn == 0 ) { delete pn; }
}
}
Or it could be fixed by adding yet another flag, and instead of having a
long as *pn, use a struct { bool released; long count; }
-gary-
This message is for the named person's use only. It may contain
confidential, proprietary or legally privileged information. No
confidentiality or privilege is waived or lost by any mistransmission.
If you receive this message in error, please immediately delete it and all
copies of it from your system, destroy any hard copies of it and notify the
sender. You must not, directly or indirectly, use, disclose, distribute,
print, or copy any part of this message if you are not the intended
recipient. CREDIT SUISSE GROUP and each of its subsidiaries each reserve
the right to monitor all e-mail communications through its networks. Any
views expressed in this message are those of the individual sender, except
where the message states otherwise and the sender is authorised to state
them to be the views of any such entity.
Unless otherwise stated, any pricing information given in this message is
indicative only, is subject to change and does not constitute an offer to
deal at any price quoted.
Any reference to the terms of executed transactions should be treated as
preliminary only and subject to our formal written confirmation.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk