[osg-users] Returning ref_ptr<> vs. ref_ptr<>::get()
robert.osfield at gmail.com
Wed Sep 10 12:00:03 PDT 2008
I won't dive in deep in this topic as it's been covered many times and
there is docs up on the wiki.
W.r.t access to .get(), yes this in theory can lead to misuse, but
it's also key to genuine uses - such as where a C pointer is required.
I tend to assume that OSG users are grown ups and know how to code, I
rather not penalise the good programmers for the inabilities of the
few engineers who can't code their way out of wet paper bag.
The code example you gave doesn't look clean, there is no need to pass
back a C pointer from a function that returns a ref_ptr<>, unless the
types of different. Cases where the types can be different is when
using a ref_ptr<Group> internally and then passing out a ref_ptr<Node>
as the return type, here there is now way to downcast a ref_ptr<Group>
to ref_ptr<Node>. One can do this downcast use member templates,
but... not all compilers and all the platforms we support support this
feature so we have had to make do with out it. Pain in the butt, but
that's the way of the wacky C++ world.
On a general note, I tend to use ref_ptr<> when they are required, and
C* pointers elsewhere, I choose ref_ptr<> when I want robust and easy
memory management, I use C pointers where no particular harm will come
from their usage, and performance will be gained (please note passing
ref_ptr<> around introduces thrashing of the renderenceCount() which
kills performance if you aren't careful). Mixing code with ref_ptr<>
and C* can be done perfectly safely, but you do need to understand the
consequences - ref counting is one of the fundamental concepts that
all C++ programmers need to grasp very early in their careers, long
before they even come across software like the OSG.
On Wed, Sep 10, 2008 at 7:22 PM, Cliff Taylor <bloodgain at gmail.com> wrote:
> [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
> osg-users mailing list
> osg-users at lists.openscenegraph.org
More information about the osg-users