00001 /* ==================================================== ======== ======= * 00002 * 00003 * uobject.hpp 00004 * Ubit Project 00005 * Part of the Ubit Toolkit: A Brick Construction Game Model for Creating GUIs 00006 * (C) 1999-2006 EricLecolinet / ENST Paris / http://www.enst.fr/~elc/ubit 00007 * 00008 * *********************************************************************** 00009 * COPYRIGHT NOTICE : 00010 * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY AND WITHOUT EVEN THE 00011 * IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 00012 * YOU CAN REDISTRIBUTE IT AND/OR MODIFY IT UNDER THE TERMS OF THE GNU 00013 * GENERAL PUBLIC LICENSE AS PUBLISHED BY THE FREE SOFTWARE FOUNDATION; 00014 * EITHER VERSION 2 OF THE LICENSE, OR (AT YOUR OPTION) ANY LATER VERSION. 00015 * SEE FILES 'COPYRIGHT' AND 'COPYING' FOR MORE DETAILS. 00016 * *********************************************************************** 00017 * ==================================================== [(c)Elc] ======= * 00018 * ==================================================== ======== ======= */ 00019 00020 #ifndef _uobject_hpp_ 00021 #define _uobject_hpp_ 00022 //pragma ident "@(#)uobject.hpp ubit:05.05.00" 00023 #include <ubit/udefs.hpp> 00024 namespace ubit { 00025 00030 class UObject { 00031 public: 00032 static const char* getVersion(); 00034 00035 const char* getTypeName() const; 00042 virtual const UStr& getClassName() const; 00050 virtual const UClass& getClass() const {return classid();} 00051 /* virtual function that returns the Ubit Class of this object (see details!). 00052 * this function MUST be redefined by ALL UObject subclassses. This can be done 00053 * by inserting one of the UCLASS, UELEMENT_CLASS or UATTRIBUTE_CLASS macros 00054 * in the class declaration (see examples in UObject subclasses) 00055 * @see: classid(), UClass. 00056 */ 00057 00058 static const UClass& classid(); 00059 /* static function that returns the UClass of this class (see details!). 00060 * this function MUST be redefined by ALL UObject subclassses. This can be done 00061 * by inserting one of the UCLASS, UELEMENT_CLASS or UATTRIBUTE_CLASS macros 00062 * in the class declaration (see examples in UObject subclasses) 00063 * @see: getClass(), UClass. 00064 */ 00065 00066 virtual UBrick* brickCast() {return null;} 00067 virtual UProp* propCast() {return null;} 00068 virtual UData* dataCast() {return null;} 00069 virtual UStr* strCast() {return null;} 00070 virtual UCall* callCast() {return null;} 00071 virtual UGroup* groupCast() {return null;} 00072 virtual UBox* boxCast() {return null;} 00073 virtual UWin* winCast() {return null;} 00074 virtual UMenu* menuCast() {return null;} 00076 00077 void addPtr() const {++ptrcount;} 00078 00079 void removePtr() const; 00080 00081 int getPtrCount() const {return ptrcount;} 00082 00083 virtual bool canPtrDelete() const; // MUST be virtual! 00085 00086 static void deferenceError(const void*); 00087 00088 UObject() {ptrcount = 0;} 00089 00090 UObject(const UObject&) {ptrcount = 0;} 00091 00092 UObject& operator=(const UBrick&) {ptrcount = 0; return *this;} 00093 00094 virtual ~UObject() {ptrcount = -1;} 00095 //NB: prtrcount<0 means that the object has been destructed 00096 00097 private: 00098 friend class UBrick; 00099 mutable int ptrcount; 00100 }; 00101 00102 /* ==================================================== [Elc] ======= */ 00103 /* ==================================================== ===== ======= */ 00104 /* uptr<> template : Ubit Smart Pointer. 00105 * 00106 * Smart Pointers make it possible to handle objects created in the heap 00107 * in a safe way. An object pointed by a uptr<> : 00108 * - is NOT destroyed when its parents are destroyed (if this object can have parents) 00109 * - is AUTOMATICALLY destroyed when the last uptr to this object is removed 00110 * - CAN'T be destroyed by using the 'delete' primitive ('delete' is dangerous 00111 * because other pointers may reference the deleted object; hence methods 00112 * such as UGroup::remove() should be uesed instead of 'delete') 00113 * 00114 * @see: UBrick. 00115 * 00116 * Example: 00117 * <pre><tt> 00118 * uptr<UStr> p1 = new UStr("111"); 00119 * uptr<UStr> p2 = ustr("222"); 00120 * 00121 * *p1 = *p2; // copies the *content* of p2 into p1 (but p1 00122 * // (and p2 still point to different objects) 00123 * 00124 * p1 = p2; // p1 now points to the same object as p2 00125 * // the object that was formerly pointed by p1 is deleted 00126 * // as there is no other reference to it 00127 * 00128 * p1->append("xyz") // the content of the object pointed by p1 is changed 00129 * 00130 * cerr << *p1; // writes the content of the object: 222xyz 00131 * cerr << &p1; // writes the address of the object 00132 * 00133 * p1 = null; // p1 now points to null. the object that 00134 * // was pointed by p1 is deleted 00135 * </tt></pre> 00136 */ 00137 template <class CC> class uptr { 00138 public: 00139 uptr() {obj = null;} 00140 uptr(CC& _obj) {obj = &_obj; obj->addPtr();} 00141 uptr(CC* _obj) {obj = _obj; if(obj) obj->addPtr();} 00143 00144 uptr(const uptr<CC>& ref2) {obj = ref2.obj; if(obj) obj->addPtr();} 00146 00147 ~uptr() {if (obj) obj->removePtr();} 00149 00150 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 00151 00152 uptr<CC>& operator=(CC& _obj) { 00153 if(obj) obj->removePtr(); obj = &_obj; if(obj) obj->addPtr(); return *this; 00154 } 00155 uptr<CC>& operator=(CC* _obj) { 00156 if(obj) obj->removePtr(); obj = _obj; if(obj) obj->addPtr(); return *this; 00157 } 00159 00160 uptr<CC>& operator=(const uptr<CC>& p2) { 00161 if(obj) obj->removePtr(); obj = p2.obj; if(obj) obj->addPtr(); return *this; 00162 } 00164 00165 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 00166 00167 operator CC*() const {return obj;} 00169 00170 CC* operator&() const {return obj;} 00172 00173 CC& operator*() const { 00174 if (!obj) UObject::deferenceError(this); 00175 return *obj; 00176 } 00178 00179 CC* operator->() const { 00180 if (!obj) UObject::deferenceError(this); 00181 return obj; 00182 } 00184 00185 private: 00186 CC* obj; 00187 CC& operator[](int); // [] meaningless and forbidden. 00188 }; 00189 00190 00191 } 00192 #endif 00193 /* ==================================================== [TheEnd] ======= */ 00194 /* ==================================================== [(c)Elc] ======= */ 00195