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