| 1 | ///////////////////////////////////////////////////////////////////////////// |
| 2 | // Name: runtimeclass.h |
| 3 | // Purpose: topic overview |
| 4 | // Author: wxWidgets team |
| 5 | // RCS-ID: $Id$ |
| 6 | // Licence: wxWindows license |
| 7 | ///////////////////////////////////////////////////////////////////////////// |
| 8 | |
| 9 | /** |
| 10 | |
| 11 | @page overview_rtti Runtime Type Information (RTTI) |
| 12 | |
| 13 | @li @ref overview_rtti_intro |
| 14 | @li @ref overview_rtti_classinfo |
| 15 | @li @ref overview_rtti_example |
| 16 | |
| 17 | @see |
| 18 | |
| 19 | @li wxObject |
| 20 | @li wxClassInfo |
| 21 | |
| 22 | |
| 23 | <hr> |
| 24 | |
| 25 | |
| 26 | @section overview_rtti_intro Introduction |
| 27 | |
| 28 | One of the failings of C++ used to be that no runtime information was provided |
| 29 | about a class and its position in the inheritance hierarchy. Another, which |
| 30 | still persists, is that instances of a class cannot be created just by knowing |
| 31 | the name of a class, which makes facilities such as persistent storage hard to |
| 32 | implement. |
| 33 | |
| 34 | Most C++ GUI frameworks overcome these limitations by means of a set of macros |
| 35 | and functions and wxWidgets is no exception. As it originated before the |
| 36 | addition of RTTI to the C++ standard and as support for it is still missing |
| 37 | from some (albeit old) compilers, wxWidgets doesn't (yet) use it, but provides |
| 38 | it's own macro-based RTTI system. |
| 39 | |
| 40 | In the future, the standard C++ RTTI will be used though and you're encouraged |
| 41 | to use whenever possible the wxDynamicCast macro which, for the implementations |
| 42 | that support it, is defined just as dynamic_cast and uses wxWidgets RTTI for |
| 43 | all the others. This macro is limited to wxWidgets classes only and only works |
| 44 | with pointers (unlike the real dynamic_cast which also accepts references). |
| 45 | |
| 46 | Each class that you wish to be known to the type system should have a macro |
| 47 | such as DECLARE_DYNAMIC_CLASS just inside the class declaration. The macro |
| 48 | IMPLEMENT_DYNAMIC_CLASS should be in the implementation file. Note that these |
| 49 | are entirely optional; use them if you wish to check object types, or create |
| 50 | instances of classes using the class name. However, it is good to get into the |
| 51 | habit of adding these macros for all classes. |
| 52 | |
| 53 | Variations on these macros are used for multiple inheritance, and abstract |
| 54 | classes that cannot be instantiated dynamically or otherwise. |
| 55 | |
| 56 | DECLARE_DYNAMIC_CLASS inserts a static wxClassInfo declaration into the class, |
| 57 | initialized by IMPLEMENT_DYNAMIC_CLASS. When initialized, the wxClassInfo |
| 58 | object inserts itself into a linked list (accessed through wxClassInfo::first |
| 59 | and wxClassInfo::next pointers). The linked list is fully created by the time |
| 60 | all global initialisation is done. |
| 61 | |
| 62 | IMPLEMENT_DYNAMIC_CLASS is a macro that not only initialises the static |
| 63 | wxClassInfo member, but defines a global function capable of creating a dynamic |
| 64 | object of the class in question. A pointer to this function is stored in |
| 65 | wxClassInfo, and is used when an object should be created dynamically. |
| 66 | |
| 67 | wxObject::IsKindOf uses the linked list of wxClassInfo. It takes a wxClassInfo |
| 68 | argument, so use CLASSINFO(className) to return an appropriate wxClassInfo |
| 69 | pointer to use in this function. |
| 70 | |
| 71 | The function wxCreateDynamicObject can be used to construct a new object of a |
| 72 | given type, by supplying a string name. If you have a pointer to the |
| 73 | wxClassInfo object instead, then you can simply call wxClassInfo::CreateObject. |
| 74 | |
| 75 | |
| 76 | @section overview_rtti_classinfo wxClassInfo |
| 77 | |
| 78 | This class stores meta-information about classes. An application may use macros |
| 79 | such as DECLARE_DYNAMIC_CLASS and IMPLEMENT_DYNAMIC_CLASS to record runtime |
| 80 | information about a class, including: |
| 81 | |
| 82 | @li It's position in the inheritance hierarchy. |
| 83 | @li The base class name(s) (up to two base classes are permitted). |
| 84 | @li A string representation of the class name. |
| 85 | @li A function that can be called to construct an instance of this class. |
| 86 | |
| 87 | The DECLARE_... macros declare a static wxClassInfo variable in a class, which |
| 88 | is initialized by macros of the form IMPLEMENT_... in the implementation C++ |
| 89 | file. Classes whose instances may be constructed dynamically are given a global |
| 90 | constructor function which returns a new object. |
| 91 | |
| 92 | You can get the wxClassInfo for a class by using the CLASSINFO macro, e.g. |
| 93 | CLASSINFO(wxFrame). You can get the wxClassInfo for an object using |
| 94 | wxObject::GetClassInfo. |
| 95 | |
| 96 | @see |
| 97 | |
| 98 | @li wxObject |
| 99 | @li wxCreateDynamicObject |
| 100 | |
| 101 | |
| 102 | @section overview_rtti_example Example |
| 103 | |
| 104 | In a header file frame.h: |
| 105 | |
| 106 | @code |
| 107 | class wxFrame : public wxWindow |
| 108 | { |
| 109 | DECLARE_DYNAMIC_CLASS(wxFrame) |
| 110 | |
| 111 | private: |
| 112 | wxString m_title; |
| 113 | |
| 114 | public: |
| 115 | ... |
| 116 | }; |
| 117 | @endcode |
| 118 | |
| 119 | In a C++ file frame.cpp: |
| 120 | |
| 121 | @code |
| 122 | IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow) |
| 123 | |
| 124 | wxFrame::wxFrame() |
| 125 | { |
| 126 | ... |
| 127 | } |
| 128 | @endcode |
| 129 | |
| 130 | */ |
| 131 | |