home *** CD-ROM | disk | FTP | other *** search
- /*
- File: Object.h
-
- Contains: Support for Base and Reference Counted Objects
- Written by: Steve Sisak
- Copyright: © 1996 by Steve Sisak, all rights reserved.
- */
-
- #ifndef __OBJECT__
- #define __OBJECT__
- #pragma once
-
- #ifndef __LANGUAGEFEATURES__
- #include "LanguageFeatures.h"
- #endif
- #ifndef __CLASSDESC__
- #include "ClassDesc.h"
- #endif
- #ifndef __EXCEPTIONS__
- #include "Exceptions.h"
- #endif
- #ifndef __TYPES__
- #include <Types.h>
- #endif
-
- //----------------------------------------------------------------------------
- // TObject - base class for dynamically allocated objects - also has stub
- // support for reference counting
- //
- // I've decided to incorporate the reference count directly instead of as
- // a mix-in as the field itself is no larger than a pointer to the base
- // class and it can be useful in debugging even with stack-based objects
- //
- //----------------------------------------------------------------------------
-
- class TObject
- #if qObjectInspector
- : public ClassDesc::ObjectRef
- #endif
- {
- DeclareClassNoBaseAbstract();
-
- protected:
- long fReferenceCount;
-
- #if qDebug
- void* fBaseAddress;
- char* fClassName;
-
- inline TObject() : fReferenceCount(0), fBaseAddress(nil), fClassName(nil) {}
- public:
- virtual ~TObject() = 0;
- #else
- inline TObject() : fReferenceCount(0) {}
- public:
- virtual ~TObject() = 0 {};
- #endif
-
- inline void NewReference() const;
- inline void DeleteReference() const;
- inline long GetReferenceCount() const;
-
- protected:
- virtual void Initialize(); // called by factory after construction
- virtual void Finalize(); // called just before destruction
- virtual void Delete(); // force a delete - warns if refcount != 1
-
- virtual TObject* DeepClone() const; // create an exact copy on this object
-
- public:
-
- #if qDebug
- virtual const char* GetClassName() const;
- virtual const void* GetBaseAddress() const;
- virtual void WriteToDebugger(bool flush = true) const;
- #else
- inline void WriteToDebugger(bool flush = true) const { flush; }
- #endif
-
- // Helper functions for the templates below
-
- static void NilObjectReference();
-
- static void InitializeObject(const TObject* obj);
- static void FinalizeObject(const TObject* obj);
- static void DeleteObject(const TObject* obj);
-
- static TObject* NewObjectRef(const TObject* obj);
- static TObject& NewObjectRef(const TObject& obj);
- static TObject* DeleteObjectRef(const TObject* obj);
- static inline void DeleteObjectRef(const TObject& obj) { DeleteObjectRef(&obj); }
- static TObject* SwapObjectRef(const TObject* dec, const TObject* inc);
- static TObject& SwapObjectRef(const TObject& dec, const TObject& inc);
- // Atomically increments the refcount of one object and decrements another
- // (either may be nil as well). This is used to support reference-counted
- // assignments
-
- };
-
-
-
- // Helper class for when a TObject is declared on the stack -- the constructor initializes
- // the object, the destructor finalizes it (with all appropriate bookkeeping)
-
- class ObjectInitializer
- {
- const TObject& fObject;
-
- public:
- ObjectInitializer(const TObject& obj);
- ~ObjectInitializer();
- };
-
- inline void TObject::NewReference() const
- {
- long count = fReferenceCount;
-
- if (count <= 0)
- InitializeObject(this);
- else
- const_cast<TObject*>(this)->fReferenceCount = count + 1;
- }
-
- inline void TObject::DeleteReference() const
- {
- long count = fReferenceCount - 1;
-
- if (count <= 0)
- DeleteObject(this);
- else
- const_cast<TObject*>(this)->fReferenceCount = count;
- }
-
- inline long TObject::GetReferenceCount() const
- {
- return fReferenceCount;
- }
-
- #if 0
-
- // helper functions for subclasses -- this would be member templates if
- // Codewarrior allowed them -- they should be simple enough that they will
- // always inline, but you never know
-
- template<class T>
- inline T* NewObjectRef(T* obj)
- {
- // if (obj != nil) CodeWarrior won't inline this!!!!
- {
- Object::NewObjectRef(obj);
- }
-
- return obj;
- }
- /*
- template<class T>
- inline T& NewObjectRef(T& obj)
- {
- // if (obj != nil) CodeWarrior won't inline this!!!!
- {
- Object::NewObjectRef(obj);
- }
-
- return obj;
- }
- */
- template<class T>
- inline T* DeleteObjectRef(T* obj)
- {
- // if (obj) CodeWarrior won't inline this!!!!
- {
- Object::DeleteObjectRef(obj);
- }
-
- return nil;
- }
-
- template<class T, class T1>
- inline T* SwapObjectRef(T1* inc, T* dec)
- {
- // const TObject* inc1 = inc;
- // const TObject* dec1 = dec;
- //
- // if (inc1 != dec1)
- {
- Object::SwapObjectRef(inc, dec);
- }
-
- return inc;
- }
-
- template<class T, class T1>
- inline T& SwapObjectRef(T1& inc, T& dec)
- {
- // const TObject* inc1 = inc;
- // const TObject* dec1 = dec;
- //
- // if (inc1 != dec1)
- {
- Object::SwapObjectRef(inc, dec);
- }
-
- return inc;
- }
-
- #endif
-
- #endif // __OBJECT__
-