Updated wxWeakRef<T> to patch Weak references for wx - part 2, removed T*() and added T* get(), other minor docs corr

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@51100 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2008-01-08 09:55:21 +00:00
parent c22eea9c9f
commit 9dd5ff5baa
4 changed files with 143 additions and 47 deletions

View File

@@ -40,12 +40,12 @@ Destructor.
Returns pointer to object or NULL. Returns pointer to object or NULL.
\membersection{wxScopedPtr<T>::operator*}\label{wxscopedptrtemplateoperatorptrt} \membersection{wxScopedPtr<T>::operator*}\label{wxscopedptrtemplateoperatorreft}
\constfunc{T \&}{operator*}{\void} \constfunc{T \&}{operator*}{\void}
Returns pointer to object. If the pointer is NULL this method will Returns a reference to the object. If the internal pointer is NULL
cause an assert in debug mode. this method will cause an assert in debug mode.
\membersection{wxScopedPtr<T>::operator->}\label{wxscopedptrtemplateoperatorderef} \membersection{wxScopedPtr<T>::operator->}\label{wxscopedptrtemplateoperatorderef}
@@ -58,7 +58,7 @@ cause an assert in debug mode.
\func{T*}{release}{\void} \func{T*}{release}{\void}
Returns pointer to object or NULL. Releases the current pointer and returns NULL.
\membersection{wxScopedPtr<T>::reset}\label{wxscopedptrtemplatereset} \membersection{wxScopedPtr<T>::reset}\label{wxscopedptrtemplatereset}

View File

@@ -41,11 +41,12 @@ Destructor.
Returns pointer to its object or NULL. Returns pointer to its object or NULL.
\membersection{wxSharedPtr<T>::operator*}\label{wxsharedptroperatorptrt} \membersection{wxSharedPtr<T>::operator*}\label{wxsharedptroperatorreft}
\constfunc{T\&}{operator*}{\void} \constfunc{T\&}{operator*}{\void}
Returns pointer to its object or NULL. Returns a reference to the object. If the internal pointer is NULL this
method will cause an assert in debug mode.
\membersection{wxSharedPtr<T>::operator->}\label{wxsharedptroperatorderef} \membersection{wxSharedPtr<T>::operator->}\label{wxsharedptroperatorderef}
@@ -71,3 +72,10 @@ Returns true if this is the only pointer pointing to its object.
Returns the number of pointers pointing to its object. Returns the number of pointers pointing to its object.
\membersection{wxSharedPtr<T>::reset}\label{wxsharedptrreset}
\func{void}{reset}{\param{T * }{ptr = NULL}}
Reset pointer to {\it ptr}. Afterwards the caller is responsible
for deleting the data contained in the pointer before.

View File

@@ -1,18 +1,66 @@
\section{\class{wxWeakRef<T>}}\label{wxweakref} \section{\class{wxWeakRef<T>}}\label{wxweakref}
A weak reference to an object of type T, where T has type {\bf wxWeakRef} is a template class for weak references to wxWidgets objects,
\helpref{wxTrackableBase}{wxtrackablebase} as one of its such as {\bf wxEvtHandler}, {\bf wxWindow} and {\bf wxObject}. A weak
base classes (in a static or dynamic sense). reference behaves much like an ordinary pointer, but when the object pointed
to goes out of scope (is destroyed), the weak reference is automatically
reset to a NULL pointer.
wxWeakref<T> can be used whenever one must keep a pointer to an object
that does not directly own, and that may be destroyed before the object
holding the reference.
wxWeakref<T> is a small object and the mechanism behind it is fast
({\bf O(1)}). So the overall cost of using it is small.
\wxheading{Example}
\begin{verbatim} \begin{verbatim}
class MyClass: public Foo, public TrackableBase wxWindow *parent = /* Get parent window from somewhere */;
{ wxWindow *wnd = new wxWindow( parent, wxID_ANY, "wxWindow" );
// whatever wxWeakRef<wxWindow> wr = wnd;
} wxWindowRef wr2 = wnd; // Same as above, but using a typedef
// Do things with window
typedef wxWeakRef<MyClass> MyClassRef; wnd->Show( true );
// Weak ref is used like an ordinary pointer
wr->Show( false );
wnd->Destroy();
// Now the weak ref has been reset, so we don't risk accessing
// a dangling pointer:
wxASSERT( wr==NULL );
\end{verbatim} \end{verbatim}
wxWeakref<T> works for any objects that are derived from {\bf wxTrackableBase}
or {\bf wxTrackable}. By default, wxEvtHandler and wxWindow derive from
wxTrackableBase. However, wxObject does not, so types like {\bf wxFont} and
{\bf wxColour} are not trackable. The example below shows how to create a
wxObject derived class that is trackable:
\begin{verbatim}
class wxMyTrackableObject : public wxObject, public wxTrackable {
// ... other members here
};
\end{verbatim}
{\bf Note:} Custom trackable objects should derive from wxTrackable
if one wants to reference them from a {\bf wxWeakRef<wxObject>}. The
difference between the two base classes is that wxTrackableBase
has no virtual member functions (no VTable), and thus cannot be detected
through {\bf dynamic_cast<>}.
\wxheading{Predefined types}
The following types of weak references are predefined:
\begin{verbatim}
typedef wxWeakRef<wxObject> wxObjectRef;
typedef wxWeakRef<wxEvtHandler> wxEvtHandlerRef;
typedef wxWeakRef<wxWindow> wxWindowRef;
\end{verbatim}
\wxheading{Derived from} \wxheading{Derived from}
wxTrackerNode wxTrackerNode
@@ -30,7 +78,8 @@ wxTrackerNode
\func{}{wxWeakRef<T>}{\param{T* }{pobj = NULL}} \func{}{wxWeakRef<T>}{\param{T* }{pobj = NULL}}
Constructor. Constructor. The weak reference is initialized to {\it pobj}.
\membersection{wxWeakRef<T>::\destruct{wxWeakRef<T>}}\label{wxweakrefdtor} \membersection{wxWeakRef<T>::\destruct{wxWeakRef<T>}}\label{wxweakrefdtor}
@@ -38,36 +87,46 @@ Constructor.
Destructor. Destructor.
\membersection{wxWeakRef<T>::T*}\label{wxweakreft}
\func{operator}{T*}{\void} \membersection{wxWeakRef<T>::get}\label{wxweakrefget}
\constfunc{T *}{get}{\void}
Returns pointer to the tracked object or NULL.
\membersection{wxWeakRef<T>::operator*}\label{wxweakrefoperatorreft}
\constfunc{T \&}{operator*}{\void}
Returns a reference to the tracked object. If the internal pointer is NULL
this method will cause an assert in debug mode.
Returns pointer to tracked object or NULL.
\membersection{wxWeakRef<T>::operator->}\label{wxweakrefoperatorderef} \membersection{wxWeakRef<T>::operator->}\label{wxweakrefoperatorderef}
\func{T*}{operator->}{\void} \func{T*}{operator->}{\void}
Returns pointer to tracked object or NULL. Smart pointer member access. Returns a pointer to the
tracked object. If the internal pointer is NULL this
method will cause an assert in debug mode.
\membersection{wxWeakRef<T>::operator=}\label{wxweakrefoperatorassign} \membersection{wxWeakRef<T>::operator=}\label{wxweakrefoperatorassign}
\func{T* operator}{operator=}{\param{T* }{pobj}} \func{T* operator}{operator=}{\param{T* }{pobj}}
Assigns pointer to trackable object to this weak reference. Releases the currently tracked object and starts tracking {\it pobj}.
A weak reference may be reset by passing {\it NULL} as {\it pobj}.
\membersection{wxWeakRef<T>::Assign}\label{wxweakrefassign}
\func{void}{Assign}{\param{T* }{pobj}} \membersection{wxWeakRef<T>::operator =}\label{wxweakrefoperatorassign2}
This uses static\_cast if possible or dynamic\_cast otherwise. \func{T* operator}{operator =}{\param{wxWeakRef<T>\& }{wr}}
\membersection{wxWeakRef<T>::GetTrackable}\label{wxweakrefgettrackable} Release currently tracked object and start tracking the same object as
the wxWeakRef {\it wr}.
\func{wxTrackableBase*}{GetTrackable}{\param{T* }{pobj}}
Returns the trackable objects to which the weak reference
points or NULL if it has been destroyed.
\membersection{wxWeakRef<T>::OnObjectDestroy}\label{wxweakrefonobjectdestroy} \membersection{wxWeakRef<T>::OnObjectDestroy}\label{wxweakrefonobjectdestroy}

View File

@@ -3,7 +3,7 @@
// Purpose: wxWeakRef - Generic weak references for wxWidgets // Purpose: wxWeakRef - Generic weak references for wxWidgets
// Author: Arne Steinarson // Author: Arne Steinarson
// Created: 2007-12-27 // Created: 2007-12-27
// RCS-ID: $Id:$ // RCS-ID: $Id$
// Copyright: (c) 2007 Arne Steinarson // Copyright: (c) 2007 Arne Steinarson
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@@ -19,19 +19,42 @@ template<class T>
class wxWeakRef : public wxTrackerNode class wxWeakRef : public wxTrackerNode
{ {
public: public:
typedef T element_type;
wxWeakRef(T *pobj = NULL) : m_pobj(NULL) { Assign(pobj); } wxWeakRef(T *pobj = NULL) : m_pobj(NULL) { Assign(pobj); }
virtual ~wxWeakRef() { Assign(NULL); } virtual ~wxWeakRef() { Assign(NULL); }
// Smart pointer functions T * get() const
operator T*(){ return m_pobj; } {
T* operator->(){ return m_pobj; } return m_pobj;
}
T* operator->()
{
wxASSERT(m_pobj != NULL);
return m_pobj;
}
T& operator*() const
{
wxASSERT(m_pobj != NULL);
return *m_pobj;
}
T* operator=(T *pobj) T* operator=(T *pobj)
{ {
Assign(pobj); Assign(pobj);
return m_pobj; return m_pobj;
} }
// Assign from another weak ref, point to same object
T* operator = (const wxWeakRef<T> &wr)
{
Assign(wr);
return m_pobj;
}
virtual void OnObjectDestroy() virtual void OnObjectDestroy()
{ {
// Tracked object itself removes us from list of trackers // Tracked object itself removes us from list of trackers
@@ -39,15 +62,11 @@ public:
m_pobj = NULL; m_pobj = NULL;
} }
virtual wxTrackerNodeType GetType() { return WeakRef; }
protected: protected:
wxTrackableBase *GetTrackable(T *pobj) friend class wxTrackableBase;
{ friend class wxEvtHandler;
// this uses static_cast if possible or dynamic_cast otherwise
return wxTrackableCaster<T, wxHasBase<T, wxTrackableBase>::value> virtual wxTrackerNodeType GetType() { return WeakRef; }
::Cast(pobj);
}
void Assign(T* pobj) void Assign(T* pobj)
{ {
@@ -58,18 +77,28 @@ protected:
if ( m_pobj ) if ( m_pobj )
{ {
// Remove ourselves from object tracker list // Remove ourselves from object tracker list
GetTrackable(m_pobj)->RemoveNode(this); // This does static_cast if available, otherwise it tries dynamic cast
wxTrackableBase *pt = wxTrackableCaster<T,wxHasBase<T,wxTrackableBase>::value >::Cast(m_pobj);
wxASSERT(pt);
pt->RemoveNode(this);
m_pobj = NULL; m_pobj = NULL;
} }
// Now set new trackable object // Now set new trackable object
if ( pobj ) if ( pobj )
{ {
wxTrackableBase * const pt = GetTrackable(pobj); wxTrackableBase *pt = wxTrackableCaster<T,wxHasBase<T,wxTrackableBase>::value >::Cast(pobj);
wxCHECK_RET( pt, "type must derive from wxTrackableBase" ); if( pt )
{
pt->AddNode(this); pt->AddNode( this );
m_pobj = pobj; m_pobj = pobj;
}
else
{
// If the tracked we want to track does not support wxTackableBase, then
// log a message and keep the NULL object pointer.
wxLogWarning( _T("wxWeakRef::Assign - Type does not provide wxTrackableBase - resetting tracked object") );
}
} }
} }