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