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