469,282 Members | 1,743 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,282 developers. It's quick & easy.

To use or not to use smart pointers?

I had a 3 hours meeting today with some fellow programmers that are partly
not convinced about using smart pointers in C++. Their main concern is a
possible performance impact. I've been explaining the advantages of smart
pointers endlessly (which are currently used in all our C++ software; we
use the Boost smart pointers) as I'm seriously concerned that there is a
shift to raw pointers. We are not developing system software but rather
normal Windows programs (with exceptions turned on). I wouldn't want to
write a C++ program without smart pointers any more but after that endless
discussion I wonder if I'm too strict. Any serious arguments not to use
smart pointers?

Boris
Jul 18 '07
54 11376
On Tue, 24 Jul 2007 07:39:36 -0700, kwikius wrote:
>That only leaves one problem which is the root node. You can either
declare it on the stack or new it on the heap, though then you have to
remember to delete. This does amount to a problem, since exceptions
are quite a frequent occurence, due to say trying to access nodes that
don't exist so you now have to think about management.
This is not your problem. You provide an interface that can be used
without dynamic allocation. When a few users 'new' the root node (for
whatever reasons) it's their task to provide proper cleanup code.
>Declaring the root on the stack means you have to use a different
syntax , e.g &root rather than root, and it is slightly less flexible
as it is more difficult to modify the code, if say you want to make
the old root a sub node of some new super-root. This is quite possible
e.g in a GUI menu-tree.
Your interface currently is a little Boost-like. Try to refactor it to
a more user-friendly form.
--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch
Jul 24 '07 #51
On 24 Jul, 18:46, rpbg...@yahoo.com (Roland Pibinger) wrote:
On Tue, 24 Jul 2007 07:39:36 -0700, kwikius wrote:
That only leaves one problem which is the root node. You can either
declare it on the stack or new it on the heap, though then you have to
remember to delete. This does amount to a problem, since exceptions
are quite a frequent occurence, due to say trying to access nodes that
don't exist so you now have to think about management.

This is not your problem. You provide an interface that can be used
without dynamic allocation. When a few users 'new' the root node (for
whatever reasons) it's their task to provide proper cleanup code.
Its interesting. If I use a smart pointer for the root node, then the
whole tree is despite the term pointer, in fact an object that cleans
itself up. Its not my or the users problem

If OTOH for raw pointers I use a newed pointer for the root rather
than putting on the stack, then the simplicity is gone.

And I don't like declaring on the stack because this makes the root
semantics different to the rest.

Overall I'm erring back in favour of the smart pointer approach,
beacause with the raw pointer version I'm starting to have to think
about this and that, where it was all pretty simple previously.
Declaring the root on the stack means you have to use a different
syntax , e.g &root rather than root, and it is slightly less flexible
as it is more difficult to modify the code, if say you want to make
the old root a sub node of some new super-root. This is quite possible
e.g in a GUI menu-tree.

Your interface currently is a little Boost-like. Try to refactor it to
a more user-friendly form.
I'm not sure if you are referring to the use of free functions?

I'm not claiming its pretty anyway or high performance etc. Its just a
hack really at the moment. As usual though.. hack in haste... repent
at leisure :-)

regards
Andy Little

Jul 25 '07 #52

"Boris" <bo***@gtemail.netwrote in message
news:op***************@burk.mshome.net...
On Tue, 24 Jul 2007 11:55:19 +0200, James Kanze <ja*********@gmail.com>
wrote:
[major snip]

Can someone sum up (I'm not asking for an end to it) this thread? Because I
think it may have some (but I don't see what all the hullabalu could
possibly be about) value (because of all the posts and the topic) but I'm
too lazy to read and grok it all from the beginning. Or can someone at least
sum up the major points? (Just a thought. And thanks if you do.)

John
(Feel free to download the parser on my website that will help you decipher
what I type without having to endure parenthetical expressions). ;)

Jul 28 '07 #53
On Jul 25, 3:44 pm, Boris <bo...@gtemail.netwrote:
On Tue, 24 Jul 2007 11:55:19 +0200, James Kanze <james.ka...@gmail.com>
wrote:
[...]
[...]And my experience is that automatically using just about any
tool results in misuse, and poor code quality. Most pointers in
my code are raw pointers, simply because most pointers are used
for navigation, in one way or another. Most "objects" are local
How do you make sure though that your pointers are not in fact
dangling pointers? Is it something the Boehm collector takes
care of?
Not directly. It does ensures that the memory won't be reused
for anything else as long as you have a pointer to it, so it's
possible to add a flag to the memory, which you assert each time
you use the pointer. But in general, you still need to use the
observer pattern, and notify all clients of the object anytime
the object ceases to exist.
I see. I don't think though that using the observer pattern makes more
sense than using smart pointers.
If smart pointers could take care of it, it doesn't. Typically,
however, the class having the pointer needs to react in some
way: remove the actual pointer from a container, or often, find
an alternative resource, or pass into a degraded functional
mode, or something along those lines. The problem is that the
reaction is too application specific to be easily handled by a
smart pointer. (Or is it? I've not given it a try, but I can
sort of imagine a smart pointer which understands something
about the container which contains it, and removes itself when
notified that the pointed to object has ceased to exist.)
Not only need all classes to support the
observer pattern for memory management. You have also a more tight
coupling than with smart pointers as A does not only own B anymore but
must register with B.
Again, if a smart pointer actually fits the bill, so much the
better. My experience has been that they rarely do.
I feel like however arguing with the wrong person as
I appreciate ideas like using garbage collectors in C++ to make memory
management easier. Developers refusing to use smart pointers because of
performance concerns might be however even less willing to use gargabe
collectors. :)
:-) Probably. For many applications, garbage collection will
actually be faster than either smart pointers or manual memory
management. But people who reject the smart pointer solution
out of hand for imagined performance issues will doubtlessly do
the same for garbage collection. (It's interesting to note that
in the presence of polymorphism, at least as it is typically
implemented in C++, a dangling pointer can result in the same
type of security hole as a buffer overflow. Garbage collection,
of course, eliminates this:-). It doesn't make an incorrect
program correct, but it does limit the dammage that can be done
because of the error.)

--
James Kanze (Gabi Software) email: ja*********@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

Jul 29 '07 #54
James Kanze wrote:
On Jul 25, 3:44 pm, Boris <bo...@gtemail.netwrote:
>On Tue, 24 Jul 2007 11:55:19 +0200, James Kanze <james.ka...@gmail.com>
wrote:
[...]
[...]And my experience is that automatically using just about any
tool results in misuse, and poor code quality. Most pointers in
my code are raw pointers, simply because most pointers are used
for navigation, in one way or another. Most "objects" are local
>How do you make sure though that your pointers are not in fact
dangling pointers? Is it something the Boehm collector takes
care of?
Not directly. It does ensures that the memory won't be reused
for anything else as long as you have a pointer to it, so it's
possible to add a flag to the memory, which you assert each time
you use the pointer. But in general, you still need to use the
observer pattern, and notify all clients of the object anytime
the object ceases to exist.
>I see. I don't think though that using the observer pattern makes more
sense than using smart pointers.

If smart pointers could take care of it, it doesn't. Typically,
however, the class having the pointer needs to react in some
way: remove the actual pointer from a container, or often, find
an alternative resource, or pass into a degraded functional
mode, or something along those lines. The problem is that the
reaction is too application specific to be easily handled by a
smart pointer. (Or is it? I've not given it a try, but I can
sort of imagine a smart pointer which understands something
about the container which contains it, and removes itself when
notified that the pointed to object has ceased to exist.)
What you can have is the observer pattern packaged within the smart pointer.
The pointer would have a method where you can register a function object to
be called when the pointee is about to be deleted through any other pointer
pointing to it. Each pointer will have its own call back object even though
the pointees are shared. You could even associate two chains of call backs
with the pointee: one list for actions to be done immediately before
destruction of the pointee and the other list for actions to be done right
after.

Implementation ideas: instead of a reference count maintain a list doubly
linked list of smart pointers (all pointing to a given pointee). Copy
construction appends to the list, destruction removes from the list. As
soon as the list goes empty (i.e., reference count == 0), you delete the
pointee. Also, you have a method for freeing that runs through the list and
calls the registered call back objects (tr1::function comes to mind). It
should also set the pointer to 0 so that future attempts to dereference
trigger an assert in the operator* or operator-method.

The call back could either be registered upon creation of the smart pointer
object or through a member function template register().
Best

Kai-Uwe Bux
Jul 29 '07 #55

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

9 posts views Thread by christopher diggins | last post: by
27 posts views Thread by Susan Baker | last post: by
4 posts views Thread by Matthias Kaeppler | last post: by
92 posts views Thread by Jim Langston | last post: by
33 posts views Thread by Ney André de Mello Zunino | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.