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

158 lines
4.8 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
** Joerg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notizen .........:
**
** 18.08.2004, NH : Urversion
** 13.05.2015, JT : Refactoring for use with Qt5, ArcGIS 10.2.5
**
** -----------------------------------------------------------------------------------------------
*/
#pragma once
#include "situation_map_common_export.h"
namespace SituationMap
{
// forward declar, declared after Refenced below.
class DeleteHandler;
/**
@class Referenced referenced.h
@brief Base class for referenced counted object classes
Base class from providing referencing counted objects. Objects from type "Referenced" should
be used in combination with the class "RefPointer" for memory handling. In this case calling
delete direcly for those objects will result in an error at runtime. Unfortunately there is
no way to check this at compile time - to declare delete operator protected does not work.
@sa RefPointer
*/
class SITUATIONMAPCOMMON_EXPORT Referenced
{
public:
/**
@name Construction
@{
*/
Referenced() { _refCount = 0; }
Referenced(const Referenced &) { _refCount = 0; }
/** @} */
/**
Assign operator has to do nothing because is is permitted to change _refCount during assignment operation.
*/
inline Referenced &operator = (const Referenced &) { return *this; }
friend class DeleteHandler;
/** Set a DeleteHandler to which deletion of all referenced counted objects
* will be delegated to.*/
static void setDeleteHandler(DeleteHandler *handler);
/** Get a DeleteHandler.*/
static DeleteHandler *getDeleteHandler();
/** Increment the reference count by one, indicating that
this object has another pointer which is referencing it.*/
inline void ref() const { ++_refCount; }
/** Decrement the reference count by one, indicating that
a pointer to this object is referencing it. If the
reference count goes to zero, it is assumed that this object
is no longer referenced and is automatically deleted.*/
inline void unref() const;
/** Decrement the reference count by one, indicating that
a pointer to this object is referencing it. However, do
not delete it, even if ref count goes to 0. Warning, unref_nodelete()
should only be called if the user knows exactly who will
be resonsible for, one should prefer unref() over unref_nodelete()
as the later can lead to memory leaks.*/
inline void unref_nodelete() const { --_refCount; }
/** Return the number pointers currently referencing this object. */
inline int referenceCount() const { return _refCount; }
protected:
/**
Declaration of destructor is protected because only methode unref() or the delete
handler itself are allowed to destroy referenced objects.
*/
virtual ~Referenced();
mutable int _refCount;
};
/** Class for override the default delete behavior so that users can implement their own object
* deletion schemes. This might be done to help implement protection of multiple threads from deleting
* objects unintentionally.
* Note, the DeleteHandler cannot itself be reference counted, otherwise it
* would be responsible for deleting itself!
* An static auto_ptr<> is used internally in Referenced.cpp to manage the
* DeleteHandler's memory.*/
class SITUATIONMAPCOMMON_EXPORT DeleteHandler
{
public:
DeleteHandler() = default;
virtual ~DeleteHandler() = default;
/** Flush any cache of objects that need to be deleted by doing an actual delete.*/
virtual void flush() {}
static inline void doDelete(const Referenced *object) { delete object; }
/** Request the deletion of an object.
* Depending on users implementation of DeleteHandler, the delete of the object may occur
* straight away or be delayed until doDelete is called.
* The default implementation does a delete straight away.*/
virtual void requestDelete(const Referenced *object) { doDelete(object); }
}; /* DeleteHandler */
inline void Referenced::unref() const
{
--_refCount;
if (_refCount == 0)
{
if (getDeleteHandler()) getDeleteHandler()->requestDelete(this);
else delete this;
}
else if (_refCount < 0)
throw 2325;
} /* Referenced::unref */
} // SituationMap