It's beyond question that you need real pointers to access dynamically
created objects, e.g. to manage their lifetime. There's also no doubt
(to me) that destructors in combination with automatic objects, a.k.a.
RAII, are the best thing ever invented in C++. But that doesn't mean
that objects that mimic real pointers but do something 'smart' under
the hood (e.g. lifetime management) are a good idea too.
IMO this whole debate would be much more interesting with some example
high level specification (allowing for any differences in useage
between smart pointers and raw pointers), and then the anti raw
pointer enthusiasts could implement it using raw pointers and the
pro's could implement it using smart pointers. I have no doubt that if
measured in terms of raw speed the raw pointers would win hands down,
however the other part to this contest, that is admittedly harder to
judge and that would carry twice the weight, is how easy is this
thing to write and maintain?
As a warm up. Here is a somewhat vague spec of one library I found
useful. Anyone that has used a ducktyping language may see something
familiar.
One library I have found surprisingly useful is a C++ directory tree.
The thing was thrown together basically for fun but since writing it I
have found a huge variety of uses.
The tree has one interesting characteristic, which is that you can
throw any type of data into it
The tree is comprised of various types of nodes, each which carries a
unique id in its directory level. So far I have implemented the
following:
abstract_node : The ABC node, but one that can be instantiated. very
politically incorrect but useful for debugging..
leaf_node<T> : a terminal node that can holds a 'T'. N.B: where one
tree can hold infinite different and unrelated types of T.
branch_node<Container> : A branch that uses Container for its child
elements. So far I have only implemented vector and list, but ideally
it should be able to use a map.
container_with_leaf<Container> : I found it useful to have a branch
with some element accessable directly from its id. This type of node
can look like either a branch or a leaf.
The thing is implemented using boost::shared_ptr and weak_ptr and
internally uses a large amount of dynamic casting. Originally getting
a child returned a weak_ptr, but I found this extremely tedious, so I
restricted use of weak_ptr to getting a nodes parent I have thought of
reimplementing it with raw pointers to see what difference it would
make, both in terms of ease of writing the code and in terms of
performance. I suspect that the performance under shared_ptr is
extremely poor, but I also suspect that it would be more difficult to
code and maintain using raw pointers. I emphasise that I don't know
though !
At the end some code where the tree is set up as a parser for some
simplified html source. N.B This is just one specific use. I have also
used it for other things.. (I hope to publish the source for the tree
one day as part of my super-quan distro...)
As part of the above challenge, It is expected that whatever crap you
throw at the dom that you will be informed that you have done
something wrong by some sort of std::exception derived exception...
The two sides can then try to find ways to screw the others versions
up ;-)
example use... (The following only shows a small sample of its
functionality).
anything:

tr is some sort of shared_ptr in my impl. In this setup The
node ids are looked up as encountered directly in the source text.
N.B Not all function ptrs in following have the same sig ;-)
void quanta::html::doc::setup_dom_functions()
{
using quanta::dom::add_branch;
using quanta::dom::list_branch;
using quanta::dom::add_element;
list_branch:

tr html
= add_branch<std::list>(html_root,"html",&parse_html_tag);
list_branch:

tr head
= add_branch<std::list>(html,"head",&parse_head_tag);
add_element(head,"text-css",&parse_text_css);
list_branch:

tr body
= add_branch<std::list>(html,"body",&parse_body_tag);
add_element(body,"text",&parse_text);
add_element(body,"comment", &parse_comment);
//necessary to look up the correct function for the following cases
typedef void (*pf)( std::istream & ,
quanta::html::body_content_list:

tr ,
quanta::html::tag_identifier:

tr
);
add_element(body,"a",&parse_a_tag);
add_element(body,"p",static_cast<pf>(&parse_list_tag<quanta::html:

_tag>));
add_element(body,"div",static_cast<pf>(&parse_list_tag<quanta::html::div_tag>));
add_element(body,"pre",static_cast<pf>(&parse_list_tag<quanta::html:

re_tag>));
add_element(body,"span",static_cast<pf>(&parse_list_tag<quanta::html::span_tag>));
add_element(body said:
add_element(body said:
add_element(body said:
add_element(body said:
add_element(body said:
add_element(body said:
list_branch:

tr table = add_branch<std::list>(body,"table",
&parse_table_tag);
list_branch:

tr tr =
add_branch<std::list>(table,"tr",&parse_table_tr_tag);
add_element(tr,"td",&parse_table_tr_td_tag);
}
regards
Andy Little