Files
qt5-legatus-legacy/Lts/Viewer/SituationMap/Common/ref_pointer.h
T
2026-08-13 18:33:10 +02:00

227 lines
6.2 KiB
Objective-C
Executable File

/**
**
** @RDE_HEADER@
** Base class for reference counted objects
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Umgebung: Intel-PC
** Software-Umgebung: Linux, Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Pgrm-Sprache ....: C++ 11
**
** HIER/SACHN ......: P: -- ---- - --- QE
**
** Version .........: $Revision$
** -----------------------------------------------------------------------------------------------
**
** Autor ...........: Nikolaus Hanekamp, SEDG, Tel. 2906
**
** -----------------------------------------------------------------------------------------------
**
** Notizen .........:
**
** 18.08.2004, NH : Urversion
** 13.05.2015, JT : Refactoring for use with Qt5, ArcGIS 10.2.5
** adding methodes according to std::share_ptr like reset
**
** -----------------------------------------------------------------------------------------------
**
** Copyright (C) 2004 Rheinmetall Defence Electronics GmbH, D-28309 BREMEN
**
** -----------------------------------------------------------------------------------------------
*/
#pragma once
#include "referenced.h"
namespace SituationMap
{
/**
@class RefPointer ref_pointer.h
@brief Smart pointer for handling referenced counted objects
Simple class template to implement reference counted pointers or smart pointers. The RefPointer class controls the
reference counter of the object \c T the pointer points to. The class \c T have to be derived from class \c Referenced,
where the reference counter member variable is located. In case of this reference counter gets zero delete will be called
automatically.
@see Referenced
*/
template<class T> class RefPointer
{
public:
using ElementType = T;
/**
@name Construction and Destruction
@{
*/
RefPointer() : RefPointer(nullptr) {}
RefPointer(const RefPointer &rp) : RefPointer(rp._ptr) {}
explicit RefPointer(ElementType *t)
: _ptr(t)
{
static_assert(std::is_base_of<Referenced, T>::value
, "Class of template SituationMap::RefPointer have to be derived from class SituationMap::Referenced");
if (_ptr) _ptr->ref();
} /* RefPointer */
~RefPointer()
{
if (_ptr) _ptr->unref();
_ptr = nullptr;
} /* ~RefPointer */
/** @} */
/**
Checks if pointer is valid.
*/
explicit inline operator bool() const { return (_ptr != nullptr); }
/**
@name Casting
@{
*/
/**
To create reference pointer from a derived class directly this contructor template can be used.
How to use it is shown in the following example:
\code
RefPointer<AbstractMapObject> objPtr = getAbstractMapObject();
RefPointer<Participant> participantObj( objPtr );
if (participantObj != NULL)
{
...
}
\endcode
Alternatively it is posible to create \b participantObj from example above as follows:
\code
RefPointer<Participant> participantObj = RefPointer<Participant>(dynamic_cast<Participant*>(objPtr.get()));
\endcode
*/
template<class Y> explicit RefPointer(RefPointer<Y> assignPtr)
{
_ptr = dynamic_cast<T *>(assignPtr.get());
if (_ptr) _ptr->ref();
}
template<class Y> explicit RefPointer(Y *assignPtr)
{
_ptr = dynamic_cast<T *>(assignPtr);
if (_ptr) _ptr->ref();
}
/** @} */
inline RefPointer &operator = (const RefPointer &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();
return *this;
}
inline RefPointer &operator = (ElementType *ptr)
{
if (_ptr == ptr) return *this;
T *tmp_ptr = _ptr;
_ptr = 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();
return *this;
}
inline void reset() { *this = nullptr; }
inline void reset(T *ptr) { *this = ptr; }
/**
@name Comparison Operators
Compares the pointer element \c _ptr with other pointers.
@{
*/
inline bool operator == (const RefPointer &rp) const { return (_ptr == rp._ptr); }
inline bool operator != (const RefPointer &rp) const { return (_ptr != rp._ptr); }
inline bool operator < (const RefPointer &rp) const { return (_ptr < rp._ptr); }
inline bool operator > (const RefPointer &rp) const { return (_ptr > rp._ptr); }
inline bool operator == (const ElementType *ptr) const { return (_ptr == ptr); }
inline bool operator != (const ElementType *ptr) const { return (_ptr != ptr); }
inline bool operator < (const ElementType *ptr) const { return (_ptr < ptr); }
inline bool operator > (const ElementType *ptr) const { return (_ptr > ptr); }
/** @} */
/**
@name Access Operators
Get access to the pointer or the object it points to.
@{
*/
inline ElementType &operator*() { return *_ptr; }
inline const ElementType &operator*() const { return *_ptr; }
inline ElementType *operator->() { return _ptr; }
inline const ElementType *operator->() const { return _ptr; }
inline ElementType *get() { return _ptr; }
inline const ElementType *get() const { return _ptr; }
/** @} */
/**
@name Checks if the pointer is valid.
@{
*/
inline bool valid() const { return _ptr != nullptr; }
inline bool operator!() const { return _ptr == nullptr; }
/** @} */
/**
* @name Control Over Object Pointer
* Take control over the object pointed to by RefPointer, unreference but do not delete even if ref count goes to 0,
* return the pointer to the object.
* Note, do not use this unless you are 100% sure your code handles the deletion of the object correctly, and
* only use when absolutely required.
@{
*/
inline ElementType *take() { return release();}
inline ElementType *release() { T *tmp = _ptr; if (_ptr) _ptr->unref_nodelete(); _ptr = nullptr; return tmp;}
/** @} */
private:
ElementType *_ptr;
};
} // SituationMap