object.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: wx/object.h
  3. // Purpose: wxObject class, plus run-time type information macros
  4. // Author: Julian Smart
  5. // Modified by: Ron Lee
  6. // Created: 01/02/97
  7. // Copyright: (c) 1997 Julian Smart
  8. // (c) 2001 Ron Lee <ron@debian.org>
  9. // Licence: wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11. #ifndef _WX_OBJECTH__
  12. #define _WX_OBJECTH__
  13. // ----------------------------------------------------------------------------
  14. // headers
  15. // ----------------------------------------------------------------------------
  16. #include "wx/memory.h"
  17. #define wxDECLARE_CLASS_INFO_ITERATORS() \
  18. class WXDLLIMPEXP_BASE const_iterator \
  19. { \
  20. typedef wxHashTable_Node Node; \
  21. public: \
  22. typedef const wxClassInfo* value_type; \
  23. typedef const value_type& const_reference; \
  24. typedef const_iterator itor; \
  25. typedef value_type* ptr_type; \
  26. \
  27. Node* m_node; \
  28. wxHashTable* m_table; \
  29. public: \
  30. typedef const_reference reference_type; \
  31. typedef ptr_type pointer_type; \
  32. \
  33. const_iterator(Node* node, wxHashTable* table) \
  34. : m_node(node), m_table(table) { } \
  35. const_iterator() : m_node(NULL), m_table(NULL) { } \
  36. value_type operator*() const; \
  37. itor& operator++(); \
  38. const itor operator++(int); \
  39. bool operator!=(const itor& it) const \
  40. { return it.m_node != m_node; } \
  41. bool operator==(const itor& it) const \
  42. { return it.m_node == m_node; } \
  43. }; \
  44. \
  45. static const_iterator begin_classinfo(); \
  46. static const_iterator end_classinfo()
  47. // based on the value of wxUSE_EXTENDED_RTTI symbol,
  48. // only one of the RTTI system will be compiled:
  49. // - the "old" one (defined by rtti.h) or
  50. // - the "new" one (defined by xti.h)
  51. #include "wx/xti.h"
  52. #include "wx/rtti.h"
  53. #define wxIMPLEMENT_CLASS(name, basename) \
  54. wxIMPLEMENT_ABSTRACT_CLASS(name, basename)
  55. #define wxIMPLEMENT_CLASS2(name, basename1, basename2) \
  56. wxIMPLEMENT_ABSTRACT_CLASS2(name, basename1, basename2)
  57. // -----------------------------------
  58. // for pluggable classes
  59. // -----------------------------------
  60. // NOTE: this should probably be the very first statement
  61. // in the class declaration so wxPluginSentinel is
  62. // the first member initialised and the last destroyed.
  63. // _DECLARE_DL_SENTINEL(name) wxPluginSentinel m_pluginsentinel;
  64. #if wxUSE_NESTED_CLASSES
  65. #define _DECLARE_DL_SENTINEL(name, exportdecl) \
  66. class exportdecl name##PluginSentinel { \
  67. private: \
  68. static const wxString sm_className; \
  69. public: \
  70. name##PluginSentinel(); \
  71. ~name##PluginSentinel(); \
  72. }; \
  73. name##PluginSentinel m_pluginsentinel
  74. #define _IMPLEMENT_DL_SENTINEL(name) \
  75. const wxString name::name##PluginSentinel::sm_className(#name); \
  76. name::name##PluginSentinel::name##PluginSentinel() { \
  77. wxPluginLibrary *e = (wxPluginLibrary*) wxPluginLibrary::ms_classes.Get(#name); \
  78. if( e != 0 ) { e->RefObj(); } \
  79. } \
  80. name::name##PluginSentinel::~name##PluginSentinel() { \
  81. wxPluginLibrary *e = (wxPluginLibrary*) wxPluginLibrary::ms_classes.Get(#name); \
  82. if( e != 0 ) { e->UnrefObj(); } \
  83. }
  84. #else
  85. #define _DECLARE_DL_SENTINEL(name)
  86. #define _IMPLEMENT_DL_SENTINEL(name)
  87. #endif // wxUSE_NESTED_CLASSES
  88. #define wxDECLARE_PLUGGABLE_CLASS(name) \
  89. wxDECLARE_DYNAMIC_CLASS(name); _DECLARE_DL_SENTINEL(name, WXDLLIMPEXP_CORE)
  90. #define wxDECLARE_ABSTRACT_PLUGGABLE_CLASS(name) \
  91. wxDECLARE_ABSTRACT_CLASS(name); _DECLARE_DL_SENTINEL(name, WXDLLIMPEXP_CORE)
  92. #define wxDECLARE_USER_EXPORTED_PLUGGABLE_CLASS(name, usergoo) \
  93. wxDECLARE_DYNAMIC_CLASS(name); _DECLARE_DL_SENTINEL(name, usergoo)
  94. #define wxDECLARE_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS(name, usergoo) \
  95. wxDECLARE_ABSTRACT_CLASS(name); _DECLARE_DL_SENTINEL(name, usergoo)
  96. #define wxIMPLEMENT_PLUGGABLE_CLASS(name, basename) \
  97. wxIMPLEMENT_DYNAMIC_CLASS(name, basename) _IMPLEMENT_DL_SENTINEL(name)
  98. #define wxIMPLEMENT_PLUGGABLE_CLASS2(name, basename1, basename2) \
  99. wxIMPLEMENT_DYNAMIC_CLASS2(name, basename1, basename2) _IMPLEMENT_DL_SENTINEL(name)
  100. #define wxIMPLEMENT_ABSTRACT_PLUGGABLE_CLASS(name, basename) \
  101. wxIMPLEMENT_ABSTRACT_CLASS(name, basename) _IMPLEMENT_DL_SENTINEL(name)
  102. #define wxIMPLEMENT_ABSTRACT_PLUGGABLE_CLASS2(name, basename1, basename2) \
  103. wxIMPLEMENT_ABSTRACT_CLASS2(name, basename1, basename2) _IMPLEMENT_DL_SENTINEL(name)
  104. #define wxIMPLEMENT_USER_EXPORTED_PLUGGABLE_CLASS(name, basename) \
  105. wxIMPLEMENT_PLUGGABLE_CLASS(name, basename)
  106. #define wxIMPLEMENT_USER_EXPORTED_PLUGGABLE_CLASS2(name, basename1, basename2) \
  107. wxIMPLEMENT_PLUGGABLE_CLASS2(name, basename1, basename2)
  108. #define wxIMPLEMENT_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS(name, basename) \
  109. wxIMPLEMENT_ABSTRACT_PLUGGABLE_CLASS(name, basename)
  110. #define wxIMPLEMENT_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS2(name, basename1, basename2) \
  111. wxIMPLEMENT_ABSTRACT_PLUGGABLE_CLASS2(name, basename1, basename2)
  112. #define wxCLASSINFO(name) (&name::ms_classInfo)
  113. #define wxIS_KIND_OF(obj, className) obj->IsKindOf(&className::ms_classInfo)
  114. // Just seems a bit nicer-looking (pretend it's not a macro)
  115. #define wxIsKindOf(obj, className) obj->IsKindOf(&className::ms_classInfo)
  116. // this cast does some more checks at compile time as it uses static_cast
  117. // internally
  118. //
  119. // note that it still has different semantics from dynamic_cast<> and so can't
  120. // be replaced by it as long as there are any compilers not supporting it
  121. #define wxDynamicCast(obj, className) \
  122. ((className *) wxCheckDynamicCast( \
  123. const_cast<wxObject *>(static_cast<const wxObject *>(\
  124. const_cast<className *>(static_cast<const className *>(obj)))), \
  125. &className::ms_classInfo))
  126. // The 'this' pointer is always true, so use this version
  127. // to cast the this pointer and avoid compiler warnings.
  128. #define wxDynamicCastThis(className) \
  129. (IsKindOf(&className::ms_classInfo) ? (className *)(this) : (className *)0)
  130. // FIXME-VC6: dummy argument needed because VC6 doesn't support explicitly
  131. // choosing the template function to call
  132. template <class T>
  133. inline T *wxCheckCast(const void *ptr, T * = NULL)
  134. {
  135. wxASSERT_MSG( wxDynamicCast(ptr, T), "wxStaticCast() used incorrectly" );
  136. return const_cast<T *>(static_cast<const T *>(ptr));
  137. }
  138. #define wxStaticCast(obj, className) wxCheckCast((obj), (className *)NULL)
  139. // ----------------------------------------------------------------------------
  140. // set up memory debugging macros
  141. // ----------------------------------------------------------------------------
  142. /*
  143. Which new/delete operator variants do we want?
  144. _WX_WANT_NEW_SIZET_WXCHAR_INT = void *operator new (size_t size, wxChar *fileName = 0, int lineNum = 0)
  145. _WX_WANT_DELETE_VOID = void operator delete (void * buf)
  146. _WX_WANT_DELETE_VOID_CONSTCHAR_SIZET = void operator delete (void *buf, const char *_fname, size_t _line)
  147. _WX_WANT_DELETE_VOID_WXCHAR_INT = void operator delete(void *buf, wxChar*, int)
  148. _WX_WANT_ARRAY_NEW_SIZET_WXCHAR_INT = void *operator new[] (size_t size, wxChar *fileName , int lineNum = 0)
  149. _WX_WANT_ARRAY_DELETE_VOID = void operator delete[] (void *buf)
  150. _WX_WANT_ARRAY_DELETE_VOID_WXCHAR_INT = void operator delete[] (void* buf, wxChar*, int )
  151. */
  152. #if wxUSE_MEMORY_TRACING
  153. // All compilers get this one
  154. #define _WX_WANT_NEW_SIZET_WXCHAR_INT
  155. // Everyone except Visage gets the next one
  156. #ifndef __VISAGECPP__
  157. #define _WX_WANT_DELETE_VOID
  158. #endif
  159. // Only visage gets this one under the correct circumstances
  160. #if defined(__VISAGECPP__) && __DEBUG_ALLOC__
  161. #define _WX_WANT_DELETE_VOID_CONSTCHAR_SIZET
  162. #endif
  163. // Only VC++ 6 gets overloaded delete that matches new
  164. #if (defined(__VISUALC__) && (__VISUALC__ >= 1200))
  165. #define _WX_WANT_DELETE_VOID_WXCHAR_INT
  166. #endif
  167. // Now see who (if anyone) gets the array memory operators
  168. #if wxUSE_ARRAY_MEMORY_OPERATORS
  169. // Everyone except Visual C++ (cause problems for VC++ - crashes)
  170. #if !defined(__VISUALC__)
  171. #define _WX_WANT_ARRAY_NEW_SIZET_WXCHAR_INT
  172. #endif
  173. // Everyone except Visual C++ (cause problems for VC++ - crashes)
  174. #if !defined(__VISUALC__)
  175. #define _WX_WANT_ARRAY_DELETE_VOID
  176. #endif
  177. #endif // wxUSE_ARRAY_MEMORY_OPERATORS
  178. #endif // wxUSE_MEMORY_TRACING
  179. // ----------------------------------------------------------------------------
  180. // Compatibility macro aliases DECLARE group
  181. // ----------------------------------------------------------------------------
  182. // deprecated variants _not_ requiring a semicolon after them and without wx prefix.
  183. // (note that also some wx-prefixed macro do _not_ require a semicolon because
  184. // it's not always possible to force the compire to require it)
  185. #define DECLARE_CLASS_INFO_ITERATORS() wxDECLARE_CLASS_INFO_ITERATORS();
  186. #define DECLARE_ABSTRACT_CLASS(n) wxDECLARE_ABSTRACT_CLASS(n);
  187. #define DECLARE_DYNAMIC_CLASS_NO_ASSIGN(n) wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(n);
  188. #define DECLARE_DYNAMIC_CLASS_NO_COPY(n) wxDECLARE_DYNAMIC_CLASS_NO_COPY(n);
  189. #define DECLARE_DYNAMIC_CLASS(n) wxDECLARE_DYNAMIC_CLASS(n);
  190. #define DECLARE_CLASS(n) wxDECLARE_CLASS(n);
  191. #define DECLARE_PLUGGABLE_CLASS(n) wxDECLARE_PLUGGABLE_CLASS(n);
  192. #define DECLARE_ABSTRACT_PLUGGABLE_CLASS(n) wxDECLARE_ABSTRACT_PLUGGABLE_CLASS(n);
  193. #define DECLARE_USER_EXPORTED_PLUGGABLE_CLASS(n,u) wxDECLARE_USER_EXPORTED_PLUGGABLE_CLASS(n,u);
  194. #define DECLARE_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS(n,u) wxDECLARE_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS(n,u);
  195. // ----------------------------------------------------------------------------
  196. // wxRefCounter: ref counted data "manager"
  197. // ----------------------------------------------------------------------------
  198. class WXDLLIMPEXP_BASE wxRefCounter
  199. {
  200. public:
  201. wxRefCounter() { m_count = 1; }
  202. int GetRefCount() const { return m_count; }
  203. void IncRef() { m_count++; }
  204. void DecRef();
  205. protected:
  206. // this object should never be destroyed directly but only as a
  207. // result of a DecRef() call:
  208. virtual ~wxRefCounter() { }
  209. private:
  210. // our refcount:
  211. int m_count;
  212. // It doesn't make sense to copy the reference counted objects, a new ref
  213. // counter should be created for a new object instead and compilation
  214. // errors in the code using wxRefCounter due to the lack of copy ctor often
  215. // indicate a problem, e.g. a forgotten copy ctor implementation somewhere.
  216. wxDECLARE_NO_COPY_CLASS(wxRefCounter);
  217. };
  218. // ----------------------------------------------------------------------------
  219. // wxObjectRefData: ref counted data meant to be stored in wxObject
  220. // ----------------------------------------------------------------------------
  221. typedef wxRefCounter wxObjectRefData;
  222. // ----------------------------------------------------------------------------
  223. // wxObjectDataPtr: helper class to avoid memleaks because of missing calls
  224. // to wxObjectRefData::DecRef
  225. // ----------------------------------------------------------------------------
  226. template <class T>
  227. class wxObjectDataPtr
  228. {
  229. public:
  230. typedef T element_type;
  231. wxEXPLICIT wxObjectDataPtr(T *ptr = NULL) : m_ptr(ptr) {}
  232. // copy ctor
  233. wxObjectDataPtr(const wxObjectDataPtr<T> &tocopy)
  234. : m_ptr(tocopy.m_ptr)
  235. {
  236. if (m_ptr)
  237. m_ptr->IncRef();
  238. }
  239. ~wxObjectDataPtr()
  240. {
  241. if (m_ptr)
  242. m_ptr->DecRef();
  243. }
  244. T *get() const { return m_ptr; }
  245. // test for pointer validity: defining conversion to unspecified_bool_type
  246. // and not more obvious bool to avoid implicit conversions to integer types
  247. typedef T *(wxObjectDataPtr<T>::*unspecified_bool_type)() const;
  248. operator unspecified_bool_type() const
  249. {
  250. return m_ptr ? &wxObjectDataPtr<T>::get : NULL;
  251. }
  252. T& operator*() const
  253. {
  254. wxASSERT(m_ptr != NULL);
  255. return *(m_ptr);
  256. }
  257. T *operator->() const
  258. {
  259. wxASSERT(m_ptr != NULL);
  260. return get();
  261. }
  262. void reset(T *ptr)
  263. {
  264. if (m_ptr)
  265. m_ptr->DecRef();
  266. m_ptr = ptr;
  267. }
  268. wxObjectDataPtr& operator=(const wxObjectDataPtr &tocopy)
  269. {
  270. if (m_ptr)
  271. m_ptr->DecRef();
  272. m_ptr = tocopy.m_ptr;
  273. if (m_ptr)
  274. m_ptr->IncRef();
  275. return *this;
  276. }
  277. wxObjectDataPtr& operator=(T *ptr)
  278. {
  279. if (m_ptr)
  280. m_ptr->DecRef();
  281. m_ptr = ptr;
  282. return *this;
  283. }
  284. private:
  285. T *m_ptr;
  286. };
  287. // ----------------------------------------------------------------------------
  288. // wxObject: the root class of wxWidgets object hierarchy
  289. // ----------------------------------------------------------------------------
  290. class WXDLLIMPEXP_BASE wxObject
  291. {
  292. wxDECLARE_ABSTRACT_CLASS(wxObject);
  293. public:
  294. wxObject() { m_refData = NULL; }
  295. virtual ~wxObject() { UnRef(); }
  296. wxObject(const wxObject& other)
  297. {
  298. m_refData = other.m_refData;
  299. if (m_refData)
  300. m_refData->IncRef();
  301. }
  302. wxObject& operator=(const wxObject& other)
  303. {
  304. if ( this != &other )
  305. {
  306. Ref(other);
  307. }
  308. return *this;
  309. }
  310. bool IsKindOf(const wxClassInfo *info) const;
  311. // Turn on the correct set of new and delete operators
  312. #ifdef _WX_WANT_NEW_SIZET_WXCHAR_INT
  313. void *operator new ( size_t size, const wxChar *fileName = NULL, int lineNum = 0 );
  314. #endif
  315. #ifdef _WX_WANT_DELETE_VOID
  316. void operator delete ( void * buf );
  317. #endif
  318. #ifdef _WX_WANT_DELETE_VOID_CONSTCHAR_SIZET
  319. void operator delete ( void *buf, const char *_fname, size_t _line );
  320. #endif
  321. #ifdef _WX_WANT_DELETE_VOID_WXCHAR_INT
  322. void operator delete ( void *buf, const wxChar*, int );
  323. #endif
  324. #ifdef _WX_WANT_ARRAY_NEW_SIZET_WXCHAR_INT
  325. void *operator new[] ( size_t size, const wxChar *fileName = NULL, int lineNum = 0 );
  326. #endif
  327. #ifdef _WX_WANT_ARRAY_DELETE_VOID
  328. void operator delete[] ( void *buf );
  329. #endif
  330. #ifdef _WX_WANT_ARRAY_DELETE_VOID_WXCHAR_INT
  331. void operator delete[] (void* buf, const wxChar*, int );
  332. #endif
  333. // ref counted data handling methods
  334. // get/set
  335. wxObjectRefData *GetRefData() const { return m_refData; }
  336. void SetRefData(wxObjectRefData *data) { m_refData = data; }
  337. // make a 'clone' of the object
  338. void Ref(const wxObject& clone);
  339. // destroy a reference
  340. void UnRef();
  341. // Make sure this object has only one reference
  342. void UnShare() { AllocExclusive(); }
  343. // check if this object references the same data as the other one
  344. bool IsSameAs(const wxObject& o) const { return m_refData == o.m_refData; }
  345. protected:
  346. // ensure that our data is not shared with anybody else: if we have no
  347. // data, it is created using CreateRefData() below, if we have shared data
  348. // it is copied using CloneRefData(), otherwise nothing is done
  349. void AllocExclusive();
  350. // both methods must be implemented if AllocExclusive() is used, not pure
  351. // virtual only because of the backwards compatibility reasons
  352. // create a new m_refData
  353. virtual wxObjectRefData *CreateRefData() const;
  354. // create a new m_refData initialized with the given one
  355. virtual wxObjectRefData *CloneRefData(const wxObjectRefData *data) const;
  356. wxObjectRefData *m_refData;
  357. };
  358. inline wxObject *wxCheckDynamicCast(wxObject *obj, wxClassInfo *classInfo)
  359. {
  360. return obj && obj->GetClassInfo()->IsKindOf(classInfo) ? obj : NULL;
  361. }
  362. #include "wx/xti2.h"
  363. // ----------------------------------------------------------------------------
  364. // more debugging macros
  365. // ----------------------------------------------------------------------------
  366. #if wxUSE_DEBUG_NEW_ALWAYS
  367. #define WXDEBUG_NEW new(__TFILE__,__LINE__)
  368. #if wxUSE_GLOBAL_MEMORY_OPERATORS
  369. #define new WXDEBUG_NEW
  370. #elif defined(__VISUALC__)
  371. // Including this file redefines new and allows leak reports to
  372. // contain line numbers
  373. #include "wx/msw/msvcrt.h"
  374. #endif
  375. #endif // wxUSE_DEBUG_NEW_ALWAYS
  376. // ----------------------------------------------------------------------------
  377. // Compatibility macro aliases IMPLEMENT group
  378. // ----------------------------------------------------------------------------
  379. // deprecated variants _not_ requiring a semicolon after them and without wx prefix.
  380. // (note that also some wx-prefixed macro do _not_ require a semicolon because
  381. // it's not always possible to force the compire to require it)
  382. #define IMPLEMENT_DYNAMIC_CLASS(n,b) wxIMPLEMENT_DYNAMIC_CLASS(n,b)
  383. #define IMPLEMENT_DYNAMIC_CLASS2(n,b1,b2) wxIMPLEMENT_DYNAMIC_CLASS2(n,b1,b2)
  384. #define IMPLEMENT_ABSTRACT_CLASS(n,b) wxIMPLEMENT_ABSTRACT_CLASS(n,b)
  385. #define IMPLEMENT_ABSTRACT_CLASS2(n,b1,b2) wxIMPLEMENT_ABSTRACT_CLASS2(n,b1,b2)
  386. #define IMPLEMENT_CLASS(n,b) wxIMPLEMENT_CLASS(n,b)
  387. #define IMPLEMENT_CLASS2(n,b1,b2) wxIMPLEMENT_CLASS2(n,b1,b2)
  388. #define IMPLEMENT_PLUGGABLE_CLASS(n,b) wxIMPLEMENT_PLUGGABLE_CLASS(n,b)
  389. #define IMPLEMENT_PLUGGABLE_CLASS2(n,b,b2) wxIMPLEMENT_PLUGGABLE_CLASS2(n,b,b2)
  390. #define IMPLEMENT_ABSTRACT_PLUGGABLE_CLASS(n,b) wxIMPLEMENT_ABSTRACT_PLUGGABLE_CLASS(n,b)
  391. #define IMPLEMENT_ABSTRACT_PLUGGABLE_CLASS2(n,b,b2) wxIMPLEMENT_ABSTRACT_PLUGGABLE_CLASS2(n,b,b2)
  392. #define IMPLEMENT_USER_EXPORTED_PLUGGABLE_CLASS(n,b) wxIMPLEMENT_USER_EXPORTED_PLUGGABLE_CLASS(n,b)
  393. #define IMPLEMENT_USER_EXPORTED_PLUGGABLE_CLASS2(n,b,b2) wxIMPLEMENT_USER_EXPORTED_PLUGGABLE_CLASS2(n,b,b2)
  394. #define IMPLEMENT_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS(n,b) wxIMPLEMENT_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS(n,b)
  395. #define IMPLEMENT_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS2(n,b,b2) wxIMPLEMENT_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS2(n,b,b2)
  396. #define CLASSINFO(n) wxCLASSINFO(n)
  397. #endif // _WX_OBJECTH__