Re: naked pointer vs boost::shared_ptr<T>
On Mar 1, 4:02 pm, "peter koch larsen" <peter.koch.lar...@gmail.com>
wrote:
On 1 Mar., 11:10, "James Kanze" <james.ka...@gmail.com> wrote:> On Feb 28, 12:48 pm, "peter koch larsen" <peter.koch.lar...@gmail.com>
wrote:
On Feb 28, 10:24 am, "Sushrut Sardeshmukh" <bestbr...@gmail.com>
wrote:
Should we stop using naked pointer and replace all of them with
boost:shared_ptr or ( shared_array<T> or scoped_ptr) ?
The problem is not so much pointers. My recommendation is that you
should avoid any "delete" or "delete []" in your code.
So how do you delete an object with dynamic lifetime? I agree
with regards to delete[], and I don't think I've used it once in
over 15 years of C++. But delete?
Maybe you meant that all delete should be "delete this"?
No. I've rarely had a need for "delete this". I wonder where you find
this idiom useful?
Whenever I have objects which have arbitrary lifetimes, and
decide the lifetime themselves. This is almost always the case
of "modeling" objects, for example, which represent some
external entity.
In practice, one or two employers have used relationship
management schemes in which the object told the relationship
maanager to delete it, so there wasn't actually a "delete this"
in the code. But conceptually, it comes to the same thing: the
object decides when its lifetime has ended.
I am trying to come up with C to C++ conversion guidelines for a large
transformation project. Your inputs will be very valuable.
RAII (of which the above is an example) is THE paradigm to follow.
I'm not sure I follow. RAII obeys scope; if the object lifetime
obeys scope, what are you doing allocating it dynamically to
begin with? There are exceptions, of course, but a lot of the
time, rather than replacing a raw pointer with a smart pointer,
it would be better to do away with the pointer completely.
If you can get rid of the pointer, you should. But there are lots of
cases where you can't. One such case is when a factory function
returns a polymorphic object or an object that can't be copied.
That's a good example, and auto_ptr (if one wants to stick with
the standard) or scoped_ptr (if one wants the exact semantics)
can be used to advantage in such cases, if the object has scoped
lifetime. If the object doesn't have scoped lifetime, and the
Boehm collector isn't appropriate, then it may be possible to
use shared_ptr. (I think I mentionned polymorphic agents as one
case where reference counting might be an appropriate solution
in another posting.) I find that such objects generally only
represent a very small percentage of objects in the application,
however. In my applications, most objects are either value
types (which aren't allocated dynamically, so the question
doesn't occur) or entity objects (which have explicit
lifetimes). Roughly speaking (and the variance is high), I'd
say about 60% values, 30% entity objects, and 10% others. Smart
pointers, at least the classical smart pointers, are only
applicable to that last category.
Such objects would have to be dynamically allocated and
returned via a pointer, and it is in cases such as this that I
advocate the pointer to be intelligent.
Agreed, if for some reason using the Boehm collector is not
appropriate. I'm not against using a smart pointer when the
case has been analysed, and a smart pointer is appropriate. I
am against a knee jerk reaction: replace all pointers with
shared_ptr, or whatever.
In my own applications, I find that most pointers are to objects
with explicit lifetimes, and I've yet to find a smart pointer
which is applicable to them (although I've tried). About the
only other cases are polymorphic agents (which are best
collected), and singletons (where dynamical allocation is used
expressedly so that they will never be deleted). In the case of
polymorphic agents, if I can't use the Boehm collector, I will
use either auto_ptr or a shared_ptr of some type.
There are also cases where the underlying representation is in a
pointer - COM is an obvious example for Windows guys.
When dealing with an external interface, obviously, you have to
follow its rules.
I do not share
your experience with being unable to find a reasonable pointer-type.
boost::scoped_ptr or std::auto_ptr is often a fine choice, and if not
you should be able to simply use boost::shared_ptr.
When it's appropriate. I rarely find that to be the case,
however. (Maybe COM is a good example where it would be the
case. I don't know; I generally work on Unix platforms, and
have never seen or used COM.)
FWIW: historically (before I started using the Boehm collector),
my factories generally did return objects derived from
RefCntObj, the pointed to for my invasive RefCntPtr. (I still
prefer invasive reference counting in such cases, because of the
lower overhead. But if I didn't already have the class, and
could use Boost, I'd use shared_ptr anyway.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]