Add support for using SGWeakPtr with virtual base classes.
- Add SGVirtualWeakReferenced to be used as base class for reference counted objects supporting weak references and virtual base classes. - Modify SGWeakPtr to copy with SGVirtualWeakReferenced objects.
This commit is contained in:
parent
efbec8b367
commit
9975c751a7
@ -26,7 +26,9 @@
|
|||||||
/// Base class for all reference counted SimGear objects
|
/// Base class for all reference counted SimGear objects
|
||||||
/// Classes derived from this one are meant to be managed with
|
/// Classes derived from this one are meant to be managed with
|
||||||
/// the SGSharedPtr class.
|
/// the SGSharedPtr class.
|
||||||
/// For more info see @SGSharedPtr.
|
///
|
||||||
|
/// For more info see SGSharedPtr. For using weak references see
|
||||||
|
/// SGWeakReferenced.
|
||||||
|
|
||||||
class SGReferenced {
|
class SGReferenced {
|
||||||
public:
|
public:
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
#include "SGReferenced.hxx"
|
#include "SGReferenced.hxx"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class SGWeakPtr;
|
||||||
|
|
||||||
/// This class is a pointer proxy doing reference counting on the object
|
/// This class is a pointer proxy doing reference counting on the object
|
||||||
/// it is pointing to.
|
/// it is pointing to.
|
||||||
/// The SGSharedPtr class handles reference counting and possible
|
/// The SGSharedPtr class handles reference counting and possible
|
||||||
@ -43,9 +46,6 @@
|
|||||||
/// pretty much the same than this one at
|
/// pretty much the same than this one at
|
||||||
/// http://dburns.dhs.org/OSG/Articles/RefPointers/RefPointers.html
|
/// http://dburns.dhs.org/OSG/Articles/RefPointers/RefPointers.html
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class SGWeakPtr;
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class SGSharedPtr {
|
class SGSharedPtr {
|
||||||
public:
|
public:
|
||||||
|
@ -20,6 +20,10 @@
|
|||||||
|
|
||||||
#include "SGWeakReferenced.hxx"
|
#include "SGWeakReferenced.hxx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for handling weak references to classes derived from SGWeakReferenced
|
||||||
|
* or SGVirtualWeakReferenced.
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class SGWeakPtr {
|
class SGWeakPtr {
|
||||||
public:
|
public:
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
#include "SGReferenced.hxx"
|
#include "SGReferenced.hxx"
|
||||||
#include "SGSharedPtr.hxx"
|
#include "SGSharedPtr.hxx"
|
||||||
|
|
||||||
|
#include <boost/type_traits/is_base_of.hpp>
|
||||||
|
#include <boost/utility/enable_if.hpp>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(push)
|
# pragma warning(push)
|
||||||
// C4355: 'this' : used in base member initializer list
|
// C4355: 'this' : used in base member initializer list
|
||||||
@ -30,7 +33,18 @@
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class SGWeakPtr;
|
class SGWeakPtr;
|
||||||
|
class SGVirtualWeakReferenced;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for all reference counted SimGear objects supporting weak
|
||||||
|
* references, not incrementing the reference count.
|
||||||
|
*
|
||||||
|
* Classes derived from this one are meant to be managed with the SGSharedPtr
|
||||||
|
* and SGWeakPtr classes.
|
||||||
|
*
|
||||||
|
* If the class hierarchy contains virtual base classes use
|
||||||
|
* SGVirtualWeakReferenced instead.
|
||||||
|
*/
|
||||||
class SGWeakReferenced {
|
class SGWeakReferenced {
|
||||||
public:
|
public:
|
||||||
/// The object backref and the reference count for this object need to be
|
/// The object backref and the reference count for this object need to be
|
||||||
@ -89,7 +103,7 @@ private:
|
|||||||
} while (!mRefcount.compareAndExchange(count, count + 1));
|
} while (!mRefcount.compareAndExchange(count, count + 1));
|
||||||
// We know that as long as the refcount is not zero, the pointer still
|
// We know that as long as the refcount is not zero, the pointer still
|
||||||
// points to valid data. So it is safe to work on it.
|
// points to valid data. So it is safe to work on it.
|
||||||
return static_cast<T*>(mWeakReferenced);
|
return up_cast<T>(mWeakReferenced);
|
||||||
}
|
}
|
||||||
|
|
||||||
SGAtomic mRefcount;
|
SGAtomic mRefcount;
|
||||||
@ -99,6 +113,32 @@ private:
|
|||||||
WeakData(void);
|
WeakData(void);
|
||||||
WeakData(const WeakData&);
|
WeakData(const WeakData&);
|
||||||
WeakData& operator=(const WeakData&);
|
WeakData& operator=(const WeakData&);
|
||||||
|
|
||||||
|
/// Upcast in a class hierarchy with a virtual base class
|
||||||
|
template<class T>
|
||||||
|
static
|
||||||
|
typename boost::enable_if<
|
||||||
|
boost::is_base_of<SGVirtualWeakReferenced, T>,
|
||||||
|
T*
|
||||||
|
>::type
|
||||||
|
up_cast(SGWeakReferenced* ptr)
|
||||||
|
{
|
||||||
|
// First get the virtual base class, which then can be used to further
|
||||||
|
// upcast.
|
||||||
|
return dynamic_cast<T*>(static_cast<SGVirtualWeakReferenced*>(ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Upcast in a non-virtual class hierarchy
|
||||||
|
template<class T>
|
||||||
|
static
|
||||||
|
typename boost::disable_if<
|
||||||
|
boost::is_base_of<SGVirtualWeakReferenced, T>,
|
||||||
|
T*
|
||||||
|
>::type
|
||||||
|
up_cast(SGWeakReferenced* ptr)
|
||||||
|
{
|
||||||
|
return static_cast<T*>(ptr);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SGSharedPtr<WeakData> mWeakData;
|
SGSharedPtr<WeakData> mWeakData;
|
||||||
@ -107,6 +147,42 @@ private:
|
|||||||
friend class SGWeakPtr;
|
friend class SGWeakPtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for all reference counted SimGear objects with virtual base
|
||||||
|
* classes, supporting weak references.
|
||||||
|
*
|
||||||
|
* Classes derived from this one are meant to be managed with the SGSharedPtr
|
||||||
|
* and SGWeakPtr classes.
|
||||||
|
*
|
||||||
|
* @code{cpp}
|
||||||
|
*
|
||||||
|
* class Base1:
|
||||||
|
* public virtual SGVirtualWeakReferenced
|
||||||
|
* {};
|
||||||
|
*
|
||||||
|
* class Base2:
|
||||||
|
* public virtual SGVirtualWeakReferenced
|
||||||
|
* {};
|
||||||
|
*
|
||||||
|
* class Derived:
|
||||||
|
* public Base1,
|
||||||
|
* public Base2
|
||||||
|
* {};
|
||||||
|
*
|
||||||
|
* SGSharedPtr<Derived> ptr( new Derived() );
|
||||||
|
* SGWeakPtr<Derived> weak_ptr( ptr );
|
||||||
|
* SGSharedPtr<Base1> ptr1( weak_ptr.lock() );
|
||||||
|
* SGSharedPtr<Base2> ptr2( weak_ptr.lock() );
|
||||||
|
*
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
class SGVirtualWeakReferenced:
|
||||||
|
public SGWeakReferenced
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~SGVirtualWeakReferenced() {}
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(pop)
|
# pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user