]>
Commit | Line | Data |
---|---|---|
1 | \section{Run time class information 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 standard C++ 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{Run time class information 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 |