From Neil Groves, "Frequently I would like code that has a signature like: void foo(osg::ref_ptr<osg::Node> node) to work for osg::ref_ptr<osg::Group>, osg::ref_ptr<osg::Geode> etc. The behaviour of osg::ref_ptr does not mimic the behaviour of a raw pointer in this regard.
To facilitate this possibility I have added a template copy constructor and a template assignment operator. These work for safe conversions like those in my previous example, but fail as desired for non-safe conversions since the template instantiation fails during the raw pointer copy/assignment. The lack of this facility has appreciably handicapped development of generic algorithms applied to the scene graph, and I believe that this alteration will be welcomed by most of the community. If there are issues with antiquated compilers not supporting template member functions then perhaps a small piece of conditional compilation is in order. I have made the change using the latest release version (2.6) as the base. The full file is attached. I have not tested building the osg wrappers and the script binding code. I have tested the legal and illegal conversions of both copying and assignment to ensure that behave as expected on MSVC7.1, MSVC8, MSVC9, GCC 4.3."
This commit is contained in:
parent
830bb21a32
commit
99fd6ed93a
@ -26,19 +26,19 @@ class ref_ptr
|
||||
ref_ptr() : _ptr(0) {}
|
||||
ref_ptr(T* ptr) : _ptr(ptr) { if (_ptr) _ptr->ref(); }
|
||||
ref_ptr(const ref_ptr& rp) : _ptr(rp._ptr) { if (_ptr) _ptr->ref(); }
|
||||
template<class Other> ref_ptr(const ref_ptr<Other>& rp) : _ptr(rp._ptr) { if (_ptr) _ptr->ref(); }
|
||||
|
||||
~ref_ptr() { if (_ptr) _ptr->unref(); _ptr = 0; }
|
||||
|
||||
ref_ptr& operator = (const ref_ptr& rp)
|
||||
{
|
||||
if (_ptr==rp._ptr) return *this;
|
||||
T* tmp_ptr = _ptr;
|
||||
_ptr = rp._ptr;
|
||||
if (_ptr) _ptr->ref();
|
||||
// unref second to prevent any deletion of any object which might
|
||||
// be referenced by the other object. i.e rp is child of the
|
||||
// original _ptr.
|
||||
if (tmp_ptr) tmp_ptr->unref();
|
||||
assign(rp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Other> ref_ptr& operator = (const ref_ptr<Other>& rp)
|
||||
{
|
||||
assign(rp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -78,6 +78,21 @@ class ref_ptr
|
||||
void swap(ref_ptr& rp) { T* tmp=_ptr; _ptr=rp._ptr; rp._ptr=tmp; }
|
||||
|
||||
private:
|
||||
|
||||
template<class Other> void assign(const ref_ptr<Other>& rp)
|
||||
{
|
||||
if (_ptr==rp._ptr) return;
|
||||
T* tmp_ptr = _ptr;
|
||||
_ptr = rp._ptr;
|
||||
if (_ptr) _ptr->ref();
|
||||
// unref second to prevent any deletion of any object which might
|
||||
// be referenced by the other object. i.e rp is child of the
|
||||
// original _ptr.
|
||||
if (tmp_ptr) tmp_ptr->unref();
|
||||
}
|
||||
|
||||
template<class Other> friend class ref_ptr;
|
||||
|
||||
T* _ptr;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user