[1660792 ] wxObject::Dec/IncRef and wxObjectDataPtr

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44521 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2007-02-17 09:16:35 +00:00
parent c71b212607
commit 4a11340a1c
3 changed files with 110 additions and 9 deletions

View File

@@ -202,6 +202,10 @@ The {\it delete} operator is defined for debugging versions of the library only,
the identifier \_\_WXDEBUG\_\_ is defined. It takes over memory deallocation, allowing the identifier \_\_WXDEBUG\_\_ is defined. It takes over memory deallocation, allowing
wxDebugContext operations. wxDebugContext operations.
%% wxObjectRefData
\section{\class{wxObjectRefData}}\label{wxobjectrefdata} \section{\class{wxObjectRefData}}\label{wxobjectrefdata}
This class is used to store reference-counted data. Derive classes from this to This class is used to store reference-counted data. Derive classes from this to
@@ -223,19 +227,36 @@ you will need to cast to your own derived class.
\func{}{wxObjectRefData}{\void} \func{}{wxObjectRefData}{\void}
Default constructor. Initialises the {\bf m\_count} member to 1. Default constructor. Initialises the internal reference count to 1.
\membersection{wxObjectRefData::\destruct{wxObjectRefData}}\label{wxobjectrefdatadtor} \membersection{wxObjectRefData::\destruct{wxObjectRefData}}\label{wxobjectrefdatadtor}
\func{}{wxObjectRefData}{\void} \func{}{wxObjectRefData}{\void}
Destructor. Destructor. It's declared {\tt protected} so that wxObjectRefData instances will never
be destroyed directly but only as result of a \helpref{DecRef}{wxobjectrefdatadecref} call.
\membersection{wxObjectRefData::GetRefCount}\label{wxobjectrefdatagetrefcount} \membersection{wxObjectRefData::GetRefCount}\label{wxobjectrefdatagetrefcount}
\constfunc{int}{GetRefCount}{\void} \constfunc{int}{GetRefCount}{\void}
Returns the reference count associated with this shared data. Returns the reference count associated with this shared data.
When this goes to zero during a \helpref{wxObject::UnRef}{wxobjectunref}, an object When this goes to zero during a \helpref{DecRef}{wxobjectrefdatadecref} call, the object
can delete this {\bf wxObjectRefData} object. will auto-free itself.
\membersection{wxObjectRefData::DecRef}\label{wxobjectrefdatadecref}
\func{void}{DecRef}{\void}
Decrements the reference count associated with this shared data and, if it reaches zero,
destroys this instance of wxObjectRefData releasing its memory.
Please note that after calling this function, the caller should absolutely avoid to use
the pointer to this instance since it may not be valid anymore.
\membersection{wxObjectRefData::IncRef}\label{wxobjectrefdataincref}
\func{void}{IncRef}{\void}
Increments the reference count associated with this shared data.

View File

@@ -392,14 +392,83 @@ class WXDLLIMPEXP_BASE wxObjectRefData
public: public:
wxObjectRefData() : m_count(1) { } wxObjectRefData() : m_count(1) { }
virtual ~wxObjectRefData() { }
int GetRefCount() const { return m_count; } int GetRefCount() const { return m_count; }
void IncRef() { m_count++; }
void DecRef();
protected:
// this object should never be destroyed directly but only as a
// result of a DecRef() call:
virtual ~wxObjectRefData() { }
private: private:
// our refcount:
int m_count; int m_count;
}; };
// ----------------------------------------------------------------------------
// wxObjectDataPtr: helper class to avoid memleaks because of missing calls
// to wxObjectRefData::DecRef
// ----------------------------------------------------------------------------
template <class T>
class wxObjectDataPtr
{
public:
typedef T element_type;
wxEXPLICIT wxObjectDataPtr(T *ptr = NULL) : m_ptr(ptr) {}
// copy ctor
wxObjectDataPtr(const wxObjectDataPtr<T> &tocopy)
: m_ptr(tocopy.m_ptr)
{
if (m_ptr)
m_ptr->IncRef();
}
~wxObjectDataPtr()
{
if (m_ptr)
m_ptr->DecRef();
}
T *get() const { return m_ptr; }
T *operator->() const { return get(); }
void reset(T *ptr)
{
if (m_ptr)
m_ptr->DecRef();
m_ptr = ptr;
}
wxObjectDataPtr& operator=(const wxObjectDataPtr &tocopy)
{
if (m_ptr)
m_ptr->DecRef();
m_ptr = tocopy.m_ptr;
if (m_ptr)
m_ptr->IncRef();
return *this;
}
wxObjectDataPtr& operator=(T *ptr)
{
if (m_ptr)
m_ptr->DecRef();
m_ptr = ptr;
if (m_ptr)
m_ptr->IncRef();
return *this;
}
private:
T *m_ptr;
};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxObject: the root class of wxWidgets object hierarchy // wxObject: the root class of wxWidgets object hierarchy
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -520,7 +589,8 @@ public:
#ifdef _MSC_VER #ifdef _MSC_VER
return (wxClassInfo*) m_classInfo; return (wxClassInfo*) m_classInfo;
#else #else
return wx_const_cast(wxClassInfo *, m_classInfo); wxDynamicClassInfo *nonconst = wx_const_cast(wxDynamicClassInfo *, m_classInfo);
return wx_static_cast(wxClassInfo *, nonconst);
#endif #endif
} }

View File

@@ -289,6 +289,17 @@ wxObject *wxCreateDynamicObject(const wxChar *name)
} }
// ----------------------------------------------------------------------------
// wxObjectRefData
// ----------------------------------------------------------------------------
void wxObjectRefData::DecRef()
{
if ( --m_count == 0 )
delete this;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxObject // wxObject
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -310,7 +321,7 @@ void wxObject::Ref(const wxObject& clone)
if ( clone.m_refData ) if ( clone.m_refData )
{ {
m_refData = clone.m_refData; m_refData = clone.m_refData;
++(m_refData->m_count); m_refData->IncRef();
} }
} }
@@ -320,8 +331,7 @@ void wxObject::UnRef()
{ {
wxASSERT_MSG( m_refData->m_count > 0, _T("invalid ref data count") ); wxASSERT_MSG( m_refData->m_count > 0, _T("invalid ref data count") );
if ( --m_refData->m_count == 0 ) m_refData->DecRef();
delete m_refData;
m_refData = NULL; m_refData = NULL;
} }
} }