author | simon <simon> | 2002-11-21 12:02:07 (UTC) |
---|---|---|
committer | simon <simon> | 2002-11-21 12:02:07 (UTC) |
commit | 58715bab157ca913a08b7ce26c230bbc0be5f70b (patch) (side-by-side diff) | |
tree | c104abd25c1ed2450b8fe469701e77f2e132aa2d | |
parent | 74b4b55fd5f09c1b8f38228488aa5876e40c0ae3 (diff) | |
download | opie-58715bab157ca913a08b7ce26c230bbc0be5f70b.zip opie-58715bab157ca913a08b7ce26c230bbc0be5f70b.tar.gz opie-58715bab157ca913a08b7ce26c230bbc0be5f70b.tar.bz2 |
- backporting two changes from qt3:
- added QInterfacePtr template class to take over the tedious work
of manual refcounting on interface objects
- the QREFCOUNT macro no longer relies on the developer to declare
(and initialize!) a refcnt variable but defines a qtrefcount class
variable itself, that takes care of proper initialization
(fixes various missing refcounter initializations found)
Harlekin suggested to commit :)
-rw-r--r-- | library/qcom.h | 90 |
1 files changed, 89 insertions, 1 deletions
diff --git a/library/qcom.h b/library/qcom.h index 8c0fa60..9972d8f 100644 --- a/library/qcom.h +++ b/library/qcom.h @@ -64,16 +64,104 @@ struct Q_EXPORT QLibraryInterface : public QUnknownInterface #define Q_CREATE_INSTANCE( IMPLEMENTATION ) \ IMPLEMENTATION *i = new IMPLEMENTATION; \ QUnknownInterface* iface = 0; \ i->queryInterface( IID_QUnknown, &iface ); \ return iface; +template <class T> +class QInterfacePtr +{ +public: + QInterfacePtr():iface(0){} + + QInterfacePtr( T* i) { + if ( (iface = i) ) + iface->addRef(); + } + + QInterfacePtr(const QInterfacePtr<T> &p) { + if ( (iface = p.iface) ) + iface->addRef(); + } + + ~QInterfacePtr() { + if ( iface ) + iface->release(); + } + + QInterfacePtr<T> &operator=(const QInterfacePtr<T> &p) { + if ( iface != p.iface ) { + if ( iface ) + iface->release(); + if ( (iface = p.iface) ) + iface->addRef(); + } + return *this; + } + + QInterfacePtr<T> &operator=(T* i) { + if (iface != i ) { + if ( iface ) + iface->release(); + if ( (iface = i) ) + iface->addRef(); + } + return *this; + } + + bool operator==( const QInterfacePtr<T> &p ) const { return iface == p.iface; } + + bool operator!= ( const QInterfacePtr<T>& p ) const { return !( *this == p ); } + + bool isNull() const { return !iface; } + + T* operator->() const { return iface; } + + T& operator*() const { return *iface; } + + operator T*() const { return iface; } + + QUnknownInterface** operator &() const { + if( iface ) + iface->release(); + return (QUnknownInterface**)&iface; + } + + T** operator &() { + if ( iface ) + iface->release(); + return &iface; + } + +private: + T* iface; +}; + + +// internal class that wraps an initialized ulong +struct Q_EXPORT QtULong +{ + QtULong() : ref( 0 ) { } + operator unsigned long () const { return ref; } + unsigned long& operator++() { return ++ref; } + unsigned long operator++( int ) { return ref++; } + unsigned long& operator--() { return --ref; } + unsigned long operator--( int ) { return ref--; } + + unsigned long ref; +}; + #define Q_EXPORT_INTERFACE() \ extern "C" QUnknownInterface* ucm_instantiate() -#define Q_REFCOUNT ulong addRef() {return ref++;}ulong release() {if(!--ref){delete this;return 0;}return ref;} +#define Q_REFCOUNT \ +private: \ + QtULong qtrefcount; \ +public: \ + ulong addRef() {return qtrefcount++;} \ + ulong release() {if(!--qtrefcount){delete this;return 0;}return qtrefcount;} #else // QT_NO_COMPONENT struct Q_EXPORT QUnknownInterface { }; |