]>
Commit | Line | Data |
---|---|---|
1 | ///////////////////////////////////////////////////////////////////////////// | |
2 | // Name: runtimeclass.h | |
3 | // Purpose: topic overview | |
4 | // Author: wxWidgets team | |
5 | // RCS-ID: $Id$ | |
6 | // Licence: wxWindows licence | |
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 | its 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 Its 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 |