Added the conversion to unspecfied_bool to all smart pointers, added T& operator* to wxObjectDataPtr

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@51118 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2008-01-08 22:02:12 +00:00
parent b3a029f0bb
commit a60b0ddc20
7 changed files with 128 additions and 63 deletions

View File

@@ -1,11 +1,16 @@
\section{\class{wxObjectDataPtr<T>}}\label{wxobjectdataptr} \section{\class{wxObjectDataPtr<T>}}\label{wxobjectdataptr}
This is helper template class to avoid memleaks because of missing calls This is helper template class primarily written to avoid memory
to \helpref{wxObjectRefData::DecRef}{wxobjectrefdatadecref}. leaks because of missing calls to \helpref{wxObjectRefData::DecRef}{wxobjectrefdatadecref}.
Despite the name this template can actually be used for any Despite the name this template can actually be used as a
class implementing the reference counting interface and it smart pointer for any class implementing the reference
does not use or depend on wxObject. counting interface and it does not use or depend on wxObject.
The difference to \helpref{wxSharedPtr}{wxsharedptr} is that
wxObjectDataPtr relies on the reference counting to be in
the class pointed to where as wxSharedPtr implements the
reference counting itself.
\wxheading{See also} \wxheading{See also}
@@ -13,6 +18,11 @@ does not use or depend on wxObject.
\helpref{wxObjectRefData}{wxobjectrefdata}, \helpref{wxObjectRefData}{wxobjectrefdata},
\helpref{Reference counting}{trefcount} \helpref{Reference counting}{trefcount}
\helpref{wxSharedPtr}{wxsharedptr},
\helpref{wxScopedPtr}{wxscopedptrtemplate},
\helpref{wxWeakRef}{wxweakref}
\wxheading{Derived from} \wxheading{Derived from}
No base class No base class
@@ -33,8 +43,6 @@ typedef T element_type
\begin{verbatim} \begin{verbatim}
// include file
class MyCarRefData: public wxObjectRefData class MyCarRefData: public wxObjectRefData
{ {
public: public:
@@ -46,11 +54,6 @@ public:
m_price = data.m_price; m_price = data.m_price;
} }
bool operator == (const MyCarRefData& data) const
{
return m_price == data.m_price;
}
void SetPrice( int price ) { m_price = price; } void SetPrice( int price ) { m_price = price; }
int GetPrice() { return m_price; } int GetPrice() { return m_price; }
@@ -61,61 +64,45 @@ protected:
class MyCar class MyCar
{ {
public: public:
MyCar( int price ); MyCar( int price ) : m_data( new MyCarRefData )
MyCar( const MyCar& data ); {
m_data->SetPrice( price );
}
bool operator == ( const MyCar& car ) const; MyCar& operator =( const MyCar& tocopy )
bool operator != (const MyCar& car) const { return !(*this == car); } {
m_data = tocopy.m_data;
return *this;
}
bool operator == ( const MyCar& other ) const
{
if (m_data.get() == other.m_data.get()) return true;
return (m_data->GetPrice() == other.m_data->GetPrice());
}
void SetPrice( int price ); void SetPrice( int price )
int GetPrice() const; {
UnShare();
m_data->SetPrice( price );
}
int GetPrice() const
{
return m_data->GetPrice();
}
wxObjectRefPtr<MyCarRefData> m_data; wxObjectDataPtr<MyCarRefData> m_data;
protected: protected:
void UnShare(); void UnShare()
}; {
if (m_data->GetRefCount() == 1)
return;
// implementation
MyCar::MyCar( int price )
{
m_data = new MyCarRefData;
m_data.get()->SetPrice( price );
}
MyCar::MyCar( const MyCar& car )
{
m_data.reset( car.m_data.get() );
}
bool MyCar::operator == ( const MyCar& car ) const
{
if (m_data.get() == car.m_data.get()) return true;
return (*m_data.get() == *car.m_data.get());
}
void MyCar::SetPrice( int price )
{
UnShare();
m_data.get()->SetPrice( price );
}
int MyCar::GetPrice() const
{
return m_data.get()->GetPrice();
}
void MyCar::UnShare()
{
if (m_data.get()->GetCount() == 1)
return;
m_data.reset( new MyCarRefData( *m_data.get() ) ); m_data.reset( new MyCarRefData( *m_data ) );
} }
};
\end{verbatim} \end{verbatim}
@@ -142,6 +129,22 @@ class will point to, as well.
Calls \helpref{DecRef}{wxobjectrefdatadecref} on the reference Calls \helpref{DecRef}{wxobjectrefdatadecref} on the reference
counted object to which this class points. counted object to which this class points.
\membersection{wxObjectDataPtr<T>::operator unspecified\_bool\_type}\label{wxobjectdataptroperatorbool}
\constfunc{}{operator unspecified\_bool\_type}{\void}
Conversion to a boolean expression (in a variant which is not
convertable to anything but a boolean expression). If this class
contains a valid pointer it will return {\it true}, if it contains
a NULL pointer it will return {\it false}.
\membersection{wxObjectDataPtr<T>::operator*}\label{wxobjectdataptroperatorreft}
\constfunc{T \&}{operator*}{\void}
Returns a reference to the object. If the internal pointer is NULL
this method will cause an assert in debug mode.
\membersection{wxObjectDataPtr<T>::operator->}\label{wxobjectdataptroperatorpointer} \membersection{wxObjectDataPtr<T>::operator->}\label{wxobjectdataptroperatorpointer}
\constfunc{T*}{operator->}{\void} \constfunc{T*}{operator->}{\void}

View File

@@ -44,6 +44,15 @@ Destructor.
Returns pointer to object or NULL. Returns pointer to object or NULL.
\membersection{wxScopedPtr<T>::operator unspecified\_bool\_type}\label{wxscopedptrtemplateoperatorbool}
\constfunc{}{operator unspecified\_bool\_type}{\void}
Conversion to a boolean expression (in a variant which is not
convertable to anything but a boolean expression). If this class
contains a valid pointer it will return {\it true}, if it contains
a NULL pointer it will return {\it false}.
\membersection{wxScopedPtr<T>::operator*}\label{wxscopedptrtemplateoperatorreft} \membersection{wxScopedPtr<T>::operator*}\label{wxscopedptrtemplateoperatorreft}
\constfunc{T \&}{operator*}{\void} \constfunc{T \&}{operator*}{\void}

View File

@@ -49,6 +49,15 @@ Destructor.
Returns pointer to its object or NULL. Returns pointer to its object or NULL.
\membersection{wxSharedPtr<T>::operator unspecified\_bool\_type}\label{wxsharedptroperatorbool}
\constfunc{}{operator unspecified\_bool\_type}{\void}
Conversion to a boolean expression (in a variant which is not
convertable to anything but a boolean expression). If this class
contains a valid pointer it will return {\it true}, if it contains
a NULL pointer it will return {\it false}.
\membersection{wxSharedPtr<T>::operator*}\label{wxsharedptroperatorreft} \membersection{wxSharedPtr<T>::operator*}\label{wxsharedptroperatorreft}
\constfunc{T\&}{operator*}{\void} \constfunc{T\&}{operator*}{\void}

View File

@@ -50,7 +50,6 @@ difference between the two base classes is that wxTrackableBase
has no virtual member functions (no VTable), and thus cannot be detected has no virtual member functions (no VTable), and thus cannot be detected
through \texttt{dynamic\_cast<>}. through \texttt{dynamic\_cast<>}.
\wxheading{Predefined types} \wxheading{Predefined types}
The following types of weak references are predefined: The following types of weak references are predefined:
@@ -70,6 +69,10 @@ wxTrackerNode
<weakref.h> <weakref.h>
\wxheading{See also}
\helpref{wxSharedPtr}{wxsharedptr}, \helpref{wxScopedPtr}{wxscopedptrtemplate}
\wxheading{Data structures} \wxheading{Data structures}
{\small% {\small%
@@ -102,6 +105,15 @@ Destructor.
Returns pointer to the tracked object or NULL. Returns pointer to the tracked object or NULL.
\membersection{wxWeakRef<T>::operator unspecified\_bool\_type}\label{wxweakrefoperatorbool}
\constfunc{}{operator unspecified\_bool\_type}{\void}
Conversion to a boolean expression (in a variant which is not
convertable to anything but a boolean expression). If this class
contains a valid pointer it will return {\it true}, if it contains
a NULL pointer it will return {\it false}.
\membersection{wxWeakRef<T>::operator*}\label{wxweakrefoperatorreft} \membersection{wxWeakRef<T>::operator*}\label{wxweakrefoperatorreft}

View File

@@ -457,6 +457,20 @@ public:
T *get() const { return m_ptr; } T *get() const { return m_ptr; }
// test for pointer validity: defining conversion to unspecified_bool_type
// and not more obvious bool to avoid implicit conversions to integer types
typedef T *(wxObjectDataPtr<T>::*unspecified_bool_type)() const;
operator unspecified_bool_type() const
{
return m_ptr ? &wxObjectDataPtr<T>::get : NULL;
}
T& operator*() const
{
wxASSERT(m_ptr != NULL);
return *(m_ptr);
}
T *operator->() const T *operator->() const
{ {
wxASSERT(m_ptr != NULL); wxASSERT(m_ptr != NULL);

View File

@@ -55,6 +55,14 @@ public:
delete m_ptr; delete m_ptr;
} }
// test for pointer validity: defining conversion to unspecified_bool_type
// and not more obvious bool to avoid implicit conversions to integer types
typedef T *(wxScopedPtr<T>::*unspecified_bool_type)() const;
operator unspecified_bool_type() const
{
return m_ptr ? &wxScopedPtr<T>::get : NULL;
}
void reset(T * ptr = NULL) void reset(T * ptr = NULL)
{ {
if (m_ptr != ptr) if (m_ptr != ptr)

View File

@@ -55,6 +55,17 @@ public:
return *this; return *this;
} }
// test for pointer validity: defining conversion to unspecified_bool_type
// and not more obvious bool to avoid implicit conversions to integer types
typedef T *(wxSharedPtr<T>::*unspecified_bool_type)() const;
operator unspecified_bool_type() const
{
if (m_ref && m_ref->m_ptr)
return &wxSharedPtr<T>::get;
else
return NULL;
}
T& operator*() const T& operator*() const
{ {
wxASSERT(m_ref != NULL); wxASSERT(m_ref != NULL);
@@ -83,7 +94,6 @@ public:
bool unique() const { return (m_ref ? m_ref->m_count == 1 : true); } bool unique() const { return (m_ref ? m_ref->m_count == 1 : true); }
long use_count() const { return (m_ref ? (long)m_ref->m_count : 0); } long use_count() const { return (m_ref ? (long)m_ref->m_count : 0); }
operator bool() const { return (get() != NULL); }
private: private: