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}
This is helper template class to avoid memleaks because of missing calls
to \helpref{wxObjectRefData::DecRef}{wxobjectrefdatadecref}.
This is helper template class primarily written to avoid memory
leaks because of missing calls to \helpref{wxObjectRefData::DecRef}{wxobjectrefdatadecref}.
Despite the name this template can actually be used for any
class implementing the reference counting interface and it
does not use or depend on wxObject.
Despite the name this template can actually be used as a
smart pointer for any class implementing the reference
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}
@@ -13,6 +18,11 @@ does not use or depend on wxObject.
\helpref{wxObjectRefData}{wxobjectrefdata},
\helpref{Reference counting}{trefcount}
\helpref{wxSharedPtr}{wxsharedptr},
\helpref{wxScopedPtr}{wxscopedptrtemplate},
\helpref{wxWeakRef}{wxweakref}
\wxheading{Derived from}
No base class
@@ -33,8 +43,6 @@ typedef T element_type
\begin{verbatim}
// include file
class MyCarRefData: public wxObjectRefData
{
public:
@@ -46,11 +54,6 @@ public:
m_price = data.m_price;
}
bool operator == (const MyCarRefData& data) const
{
return m_price == data.m_price;
}
void SetPrice( int price ) { m_price = price; }
int GetPrice() { return m_price; }
@@ -61,61 +64,45 @@ protected:
class MyCar
{
public:
MyCar( int price );
MyCar( const MyCar& data );
bool operator == ( const MyCar& car ) const;
bool operator != (const MyCar& car) const { return !(*this == car); }
void SetPrice( int price );
int GetPrice() const;
wxObjectRefPtr<MyCarRefData> m_data;
protected:
void UnShare();
};
// implementation
MyCar::MyCar( int price )
MyCar( int price ) : m_data( new MyCarRefData )
{
m_data = new MyCarRefData;
m_data.get()->SetPrice( price );
m_data->SetPrice( price );
}
MyCar::MyCar( const MyCar& car )
MyCar& operator =( const MyCar& tocopy )
{
m_data.reset( car.m_data.get() );
m_data = tocopy.m_data;
return *this;
}
bool MyCar::operator == ( const MyCar& car ) const
bool operator == ( const MyCar& other ) const
{
if (m_data.get() == car.m_data.get()) return true;
return (*m_data.get() == *car.m_data.get());
if (m_data.get() == other.m_data.get()) return true;
return (m_data->GetPrice() == other.m_data->GetPrice());
}
void MyCar::SetPrice( int price )
void SetPrice( int price )
{
UnShare();
m_data.get()->SetPrice( price );
m_data->SetPrice( price );
}
int MyCar::GetPrice() const
int GetPrice() const
{
return m_data.get()->GetPrice();
return m_data->GetPrice();
}
void MyCar::UnShare()
wxObjectDataPtr<MyCarRefData> m_data;
protected:
void UnShare()
{
if (m_data.get()->GetCount() == 1)
if (m_data->GetRefCount() == 1)
return;
m_data.reset( new MyCarRefData( *m_data.get() ) );
m_data.reset( new MyCarRefData( *m_data ) );
}
};
\end{verbatim}
@@ -142,6 +129,22 @@ class will point to, as well.
Calls \helpref{DecRef}{wxobjectrefdatadecref} on the reference
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}
\constfunc{T*}{operator->}{\void}

View File

@@ -44,6 +44,15 @@ Destructor.
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}
\constfunc{T \&}{operator*}{\void}

View File

@@ -49,6 +49,15 @@ Destructor.
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}
\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
through \texttt{dynamic\_cast<>}.
\wxheading{Predefined types}
The following types of weak references are predefined:
@@ -70,6 +69,10 @@ wxTrackerNode
<weakref.h>
\wxheading{See also}
\helpref{wxSharedPtr}{wxsharedptr}, \helpref{wxScopedPtr}{wxscopedptrtemplate}
\wxheading{Data structures}
{\small%
@@ -102,6 +105,15 @@ Destructor.
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}

View File

@@ -457,6 +457,20 @@ public:
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
{
wxASSERT(m_ptr != NULL);

View File

@@ -55,6 +55,14 @@ public:
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)
{
if (m_ptr != ptr)

View File

@@ -55,6 +55,17 @@ public:
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
{
wxASSERT(m_ref != NULL);
@@ -83,7 +94,6 @@ public:
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); }
operator bool() const { return (get() != NULL); }
private: