[osg-users] Returning ref_ptr<> vs. ref_ptr<>::get()

Cliff Taylor bloodgain at gmail.com
Wed Sep 10 11:22:51 PDT 2008

[Part 1:]

I'm relatively new to Open Scene Graph, so please forgive me if this
has been answered a hundred times already.

In the Open Scene Graph Quick Start Guide, Paul Martz gives several
examples where his functions return a ref_ptr<>.  In almost every
case, however, he returns the raw pointer address by returning the
result of ref_ptr<>::get() on his ref_ptr<class T> object.

For a simple example, on page 37 (Section 2.1.3) he gives the following method:

osg::ref_ptr<osg::Group> createGroup()
  osg::ref_ptr<osg::Group> grp = new osg::Group;

  return grp.get()

I understand that this will (or *should*) implicitly call the ctor:
ref_ptr(T* ptr)
and create the proper ref_ptr.  What I don't understand is why he
doesn't just return "grp" and let it call the copy ctor.

At first I thought it might be a scope issue, but if "grp" falls out
of scope, "grp._ptr" goes away with it.
My second thought was that he is using a slightly less-complex ctor,
but I doubt the performance gain is measurable.

My only other thought is that when he returns, for instance, a
ref_ptr<osg::Group> from a method with a return type of
ref_ptr<osg::Node>, the ref_ptr is created dynamically instead of
coerced across ref_ptr<class T> types.  As long as it gets cast up to
a ref_ptr<base class>, however, I don't see this as a problem.

Could one of you shed some light on this for me?  Is it just a coding
style decision on his part, or is this the "right way"?  I've seen
other examples where the ref_ptr<> itself is just returned.  I feel
like this is the way to go, but I want to write only "good code" with
[Part 2:]

On a related note, there are some things about the use of ref_ptr<>
that I'm not sure I'm completely happy with.  If the OSG library is
going to make full use of ref_ptr<> for memory management, then it
seems like the member functions that take raw pointers should be
changed to use ref_ptr<> instead.

I understand that there may be cases when a new object is to be added
dynamically to another object's references, i.e.:
grp->addChild(new osg::Geode);

However, this could be handled by either providing the secondary
member functions for these special cases, or by letting the programmer
handle the conversion.  In fact, the programmer could let implicit
conversion handle this if he trusts his compiler.  Internally, classes
such as osg::Group simply use this implicit conversion when they add
the raw pointer (Node *) to their child list (see implementation of
osg::Group::insertChild).  In some cases, more than one implicit
conversion takes place (Geode * --> Node * --> ref_ptr<Node>).

I say this because it seems that using ref_ptr<>::get() breaks the
rules of reference pointers, because it allows you an easy way to
ignore the reference counting.  The class functions encourage the use
of ref_ptr::get(), as well.  While this works fine with careful
programming, it opens up some easy-to-make mistakes, and invites abuse
and the forming of bad habits by "less skilled" programmers.  If
another programmer has to maintain or debug this pointer-abusive code,
it could make finding the problems extremely difficult.  I already
know of one case where a developer simply removed all the non-required
uses of ref_ptr<> to just make another programmer's errors go away as
quickly as possible.

If I remember correctly, Java purposely doesn't give you access to the
base addresses its references point to.  At least, I can't think of an
easy way to access them.  This is all in the name of safe garbage
collection and "data hiding", which ref_ptr<>::get() feels like it's
breaking, at least to me.  Shouldn't we let ref_ptr<> do it's job and
not mess with its internal structures, for the same reason we
shouldn't call ref() and unref() on osg::Referenced family objects?

That's the view from here.  I admit to being only partially informed.
If this makes somebody on the dev team think, well, I guess that can
only be positive, even if I'm wrong.  What I would really like,
however, is for someone who knows more about what's going on in OSG to
set the record straight for me.  I'd like to hear it from your side so
I can get a feel for where OSG is coming from.  Remember, I'm new to
OSG, so talk slowly and don't hurt my feelings ;-)

Cliff Taylor

More information about the osg-users mailing list