1 // © 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /* 4 ****************************************************************************** 5 * 6 * Copyright (C) 2002-2012, International Business Machines 7 * Corporation and others. All Rights Reserved. 8 * 9 ****************************************************************************** 10 * file name: uobject.h 11 * encoding: UTF-8 12 * tab size: 8 (not used) 13 * indentation:4 14 * 15 * created on: 2002jun26 16 * created by: Markus W. Scherer 17 */ 18 19 #ifndef __UOBJECT_H__ 20 #define __UOBJECT_H__ 21 22 #include "unicode/utypes.h" 23 24 /** 25 * \file 26 * \brief C++ API: Common ICU base class UObject. 27 */ 28 29 /** 30 * \def U_NO_THROW 31 * Define this to define the throw() specification so 32 * certain functions do not throw any exceptions 33 * 34 * UMemory operator new methods should have the throw() specification 35 * appended to them, so that the compiler adds the additional NULL check 36 * before calling constructors. Without, if <code>operator new</code> returns NULL the 37 * constructor is still called, and if the constructor references member 38 * data, (which it typically does), the result is a segmentation violation. 39 * 40 * @stable ICU 4.2 41 */ 42 #ifndef U_NO_THROW 43 #define U_NO_THROW throw() 44 #endif 45 46 /*===========================================================================*/ 47 /* UClassID-based RTTI */ 48 /*===========================================================================*/ 49 50 /** 51 * UClassID is used to identify classes without using the compiler's RTTI. 52 * This was used before C++ compilers consistently supported RTTI. 53 * ICU 4.6 requires compiler RTTI to be turned on. 54 * 55 * Each class hierarchy which needs 56 * to implement polymorphic clone() or operator==() defines two methods, 57 * described in detail below. UClassID values can be compared using 58 * operator==(). Nothing else should be done with them. 59 * 60 * \par 61 * In class hierarchies that implement "poor man's RTTI", 62 * each concrete subclass implements getDynamicClassID() in the same way: 63 * 64 * \code 65 * class Derived { 66 * public: 67 * virtual UClassID getDynamicClassID() const 68 * { return Derived::getStaticClassID(); } 69 * } 70 * \endcode 71 * 72 * Each concrete class implements getStaticClassID() as well, which allows 73 * clients to test for a specific type. 74 * 75 * \code 76 * class Derived { 77 * public: 78 * static UClassID U_EXPORT2 getStaticClassID(); 79 * private: 80 * static char fgClassID; 81 * } 82 * 83 * // In Derived.cpp: 84 * UClassID Derived::getStaticClassID() 85 * { return (UClassID)&Derived::fgClassID; } 86 * char Derived::fgClassID = 0; // Value is irrelevant 87 * \endcode 88 * @stable ICU 2.0 89 */ 90 typedef void* UClassID; 91 92 U_NAMESPACE_BEGIN 93 94 /** 95 * UMemory is the common ICU base class. 96 * All other ICU C++ classes are derived from UMemory (starting with ICU 2.4). 97 * 98 * This is primarily to make it possible and simple to override the 99 * C++ memory management by adding new/delete operators to this base class. 100 * 101 * To override ALL ICU memory management, including that from plain C code, 102 * replace the allocation functions declared in cmemory.h 103 * 104 * UMemory does not contain any virtual functions. 105 * Common "boilerplate" functions are defined in UObject. 106 * 107 * @stable ICU 2.4 108 */ 109 class U_COMMON_API UMemory { 110 public: 111 112 /* test versions for debugging shaper heap memory problems */ 113 #ifdef SHAPER_MEMORY_DEBUG 114 static void * NewArray(int size, int count); 115 static void * GrowArray(void * array, int newSize ); 116 static void FreeArray(void * array ); 117 #endif 118 119 #if U_OVERRIDE_CXX_ALLOCATION 120 /** 121 * Override for ICU4C C++ memory management. 122 * simple, non-class types are allocated using the macros in common/cmemory.h 123 * (uprv_malloc(), uprv_free(), uprv_realloc()); 124 * they or something else could be used here to implement C++ new/delete 125 * for ICU4C C++ classes 126 * @stable ICU 2.4 127 */ 128 static void * U_EXPORT2 operator new(size_t size) U_NO_THROW; 129 130 /** 131 * Override for ICU4C C++ memory management. 132 * See new(). 133 * @stable ICU 2.4 134 */ 135 static void * U_EXPORT2 operator new[](size_t size) U_NO_THROW; 136 137 /** 138 * Override for ICU4C C++ memory management. 139 * simple, non-class types are allocated using the macros in common/cmemory.h 140 * (uprv_malloc(), uprv_free(), uprv_realloc()); 141 * they or something else could be used here to implement C++ new/delete 142 * for ICU4C C++ classes 143 * @stable ICU 2.4 144 */ 145 static void U_EXPORT2 operator delete(void *p) U_NO_THROW; 146 147 /** 148 * Override for ICU4C C++ memory management. 149 * See delete(). 150 * @stable ICU 2.4 151 */ 152 static void U_EXPORT2 operator delete[](void *p) U_NO_THROW; 153 154 #if U_HAVE_PLACEMENT_NEW 155 /** 156 * Override for ICU4C C++ memory management for STL. 157 * See new(). 158 * @stable ICU 2.6 159 */ new(size_t,void * ptr)160 static inline void * U_EXPORT2 operator new(size_t, void *ptr) U_NO_THROW { return ptr; } 161 162 /** 163 * Override for ICU4C C++ memory management for STL. 164 * See delete(). 165 * @stable ICU 2.6 166 */ delete(void *,void *)167 static inline void U_EXPORT2 operator delete(void *, void *) U_NO_THROW {} 168 #endif /* U_HAVE_PLACEMENT_NEW */ 169 #if U_HAVE_DEBUG_LOCATION_NEW 170 /** 171 * This method overrides the MFC debug version of the operator new 172 * 173 * @param size The requested memory size 174 * @param file The file where the allocation was requested 175 * @param line The line where the allocation was requested 176 */ 177 static void * U_EXPORT2 operator new(size_t size, const char* file, int line) U_NO_THROW; 178 /** 179 * This method provides a matching delete for the MFC debug new 180 * 181 * @param p The pointer to the allocated memory 182 * @param file The file where the allocation was requested 183 * @param line The line where the allocation was requested 184 */ 185 static void U_EXPORT2 operator delete(void* p, const char* file, int line) U_NO_THROW; 186 #endif /* U_HAVE_DEBUG_LOCATION_NEW */ 187 #endif /* U_OVERRIDE_CXX_ALLOCATION */ 188 189 /* 190 * Assignment operator not declared. The compiler will provide one 191 * which does nothing since this class does not contain any data members. 192 * API/code coverage may show the assignment operator as present and 193 * untested - ignore. 194 * Subclasses need this assignment operator if they use compiler-provided 195 * assignment operators of their own. An alternative to not declaring one 196 * here would be to declare and empty-implement a protected or public one. 197 UMemory &UMemory::operator=(const UMemory &); 198 */ 199 }; 200 201 /** 202 * UObject is the common ICU "boilerplate" class. 203 * UObject inherits UMemory (starting with ICU 2.4), 204 * and all other public ICU C++ classes 205 * are derived from UObject (starting with ICU 2.2). 206 * 207 * UObject contains common virtual functions, in particular a virtual destructor. 208 * 209 * The clone() function is not available in UObject because it is not 210 * implemented by all ICU classes. 211 * Many ICU services provide a clone() function for their class trees, 212 * defined on the service's C++ base class, and all subclasses within that 213 * service class tree return a pointer to the service base class 214 * (which itself is a subclass of UObject). 215 * This is because some compilers do not support covariant (same-as-this) 216 * return types; cast to the appropriate subclass if necessary. 217 * 218 * @stable ICU 2.2 219 */ 220 class U_COMMON_API UObject : public UMemory { 221 public: 222 /** 223 * Destructor. 224 * 225 * @stable ICU 2.2 226 */ 227 virtual ~UObject(); 228 229 /** 230 * ICU4C "poor man's RTTI", returns a UClassID for the actual ICU class. 231 * The base class implementation returns a dummy value. 232 * 233 * Use compiler RTTI rather than ICU's "poor man's RTTI". 234 * Since ICU 4.6, new ICU C++ class hierarchies do not implement "poor man's RTTI". 235 * 236 * @stable ICU 2.2 237 */ 238 virtual UClassID getDynamicClassID() const; 239 240 protected: 241 // the following functions are protected to prevent instantiation and 242 // direct use of UObject itself 243 244 // default constructor 245 // inline UObject() {} 246 247 // copy constructor 248 // inline UObject(const UObject &other) {} 249 250 #if 0 251 // TODO Sometime in the future. Implement operator==(). 252 // (This comment inserted in 2.2) 253 // some or all of the following "boilerplate" functions may be made public 254 // in a future ICU4C release when all subclasses implement them 255 256 // assignment operator 257 // (not virtual, see "Taligent's Guide to Designing Programs" pp.73..74) 258 // commented out because the implementation is the same as a compiler's default 259 // UObject &operator=(const UObject &other) { return *this; } 260 261 // comparison operators 262 virtual inline UBool operator==(const UObject &other) const { return this==&other; } 263 inline UBool operator!=(const UObject &other) const { return !operator==(other); } 264 265 // clone() commented out from the base class: 266 // some compilers do not support co-variant return types 267 // (i.e., subclasses would have to return UObject * as well, instead of SubClass *) 268 // see also UObject class documentation. 269 // virtual UObject *clone() const; 270 #endif 271 272 /* 273 * Assignment operator not declared. The compiler will provide one 274 * which does nothing since this class does not contain any data members. 275 * API/code coverage may show the assignment operator as present and 276 * untested - ignore. 277 * Subclasses need this assignment operator if they use compiler-provided 278 * assignment operators of their own. An alternative to not declaring one 279 * here would be to declare and empty-implement a protected or public one. 280 UObject &UObject::operator=(const UObject &); 281 */ 282 }; 283 284 #ifndef U_HIDE_INTERNAL_API 285 /** 286 * This is a simple macro to add ICU RTTI to an ICU object implementation. 287 * This does not go into the header. This should only be used in *.cpp files. 288 * 289 * @param myClass The name of the class that needs RTTI defined. 290 * @internal 291 */ 292 #define UOBJECT_DEFINE_RTTI_IMPLEMENTATION(myClass) \ 293 UClassID U_EXPORT2 myClass::getStaticClassID() { \ 294 static char classID = 0; \ 295 return (UClassID)&classID; \ 296 } \ 297 UClassID myClass::getDynamicClassID() const \ 298 { return myClass::getStaticClassID(); } 299 300 301 /** 302 * This macro adds ICU RTTI to an ICU abstract class implementation. 303 * This macro should be invoked in *.cpp files. The corresponding 304 * header should declare getStaticClassID. 305 * 306 * @param myClass The name of the class that needs RTTI defined. 307 * @internal 308 */ 309 #define UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(myClass) \ 310 UClassID U_EXPORT2 myClass::getStaticClassID() { \ 311 static char classID = 0; \ 312 return (UClassID)&classID; \ 313 } 314 315 #endif /* U_HIDE_INTERNAL_API */ 316 317 U_NAMESPACE_END 318 319 #endif 320