]>
Commit | Line | Data |
---|---|---|
15b6757b | 1 | ///////////////////////////////////////////////////////////////////////////// |
72844950 | 2 | // Name: refcount.h |
15b6757b FM |
3 | // Purpose: topic overview |
4 | // Author: wxWidgets team | |
5 | // RCS-ID: $Id$ | |
526954c5 | 6 | // Licence: wxWindows licence |
15b6757b FM |
7 | ///////////////////////////////////////////////////////////////////////////// |
8 | ||
880efa2a | 9 | /** |
36c9828f | 10 | |
72844950 | 11 | @page overview_refcount Reference Counting |
36c9828f | 12 | |
831e1028 | 13 | @tableofcontents |
36c9828f | 14 | |
72844950 BP |
15 | Many wxWidgets objects use a technique known as <em>reference counting</em>, |
16 | also known as <em>copy on write</em> (COW). This means that when an object is | |
17 | assigned to another, no copying really takes place. Only the reference count on | |
18 | the shared object data is incremented and both objects share the same data (a | |
19 | very fast operation). | |
36c9828f | 20 | |
72844950 BP |
21 | But as soon as one of the two (or more) objects is modified, the data has to be |
22 | copied because the changes to one of the objects shouldn't be seen in the | |
23 | others. As data copying only happens when the object is written to, this is | |
24 | known as COW. | |
36c9828f | 25 | |
72844950 BP |
26 | What is important to understand is that all this happens absolutely |
27 | transparently to the class users and that whether an object is shared or not is | |
28 | not seen from the outside of the class - in any case, the result of any | |
29 | operation on it is the same. | |
36c9828f | 30 | |
36c9828f | 31 | |
72844950 | 32 | @section overview_refcount_equality Object Comparison |
36c9828f | 33 | |
3ed3a1c8 BP |
34 | The == and != operators of @ref overview_refcount_list "the reference counted classes" |
35 | always do a <em>deep comparison</em>. This means that the equality operator | |
36 | will return @true if two objects are identical and not only if they share the | |
37 | same data. | |
36c9828f | 38 | |
72844950 | 39 | Note that wxWidgets follows the <em>STL philosophy</em>: when a comparison |
4c51a665 | 40 | operator cannot be implemented efficiently (like for e.g. wxImage's == |
72844950 BP |
41 | operator which would need to compare the entire image's data, pixel-by-pixel), |
42 | it's not implemented at all. That's why not all reference counted classes | |
43 | provide comparison operators. | |
36c9828f | 44 | |
72844950 | 45 | Also note that if you only need to do a @c shallow comparison between two |
7442b5ee | 46 | wxObject derived classes, you should not use the == and != operators but |
f0a9a84c | 47 | rather the wxObject::IsSameAs() function. |
36c9828f | 48 | |
36c9828f | 49 | |
72844950 | 50 | @section overview_refcount_destruct Object Destruction |
36c9828f | 51 | |
72844950 BP |
52 | When a COW object destructor is called, it may not delete the data: if it's |
53 | shared, the destructor will just decrement the shared data's reference count | |
54 | without destroying it. Only when the destructor of the last object owning the | |
55 | data is called, the data is really destroyed. Just like all other COW-things, | |
56 | this happens transparently to the class users so that you shouldn't care about | |
57 | it. | |
36c9828f | 58 | |
36c9828f | 59 | |
72844950 | 60 | @section overview_refcount_list List of Reference Counted Classes |
36c9828f | 61 | |
72844950 BP |
62 | The following classes in wxWidgets have efficient (i.e. fast) assignment |
63 | operators and copy constructors since they are reference-counted: | |
36c9828f | 64 | |
7442b5ee BP |
65 | @li wxAcceleratorTable |
66 | @li wxAnimation | |
67 | @li wxBitmap | |
68 | @li wxBrush | |
69 | @li wxCursor | |
70 | @li wxFont | |
660b61d7 FM |
71 | @li wxGraphicsBrush |
72 | @li wxGraphicsContext | |
73 | @li wxGraphicsFont | |
74 | @li wxGraphicsMatrix | |
75 | @li wxGraphicsPath | |
76 | @li wxGraphicsPen | |
7442b5ee BP |
77 | @li wxIcon |
78 | @li wxImage | |
79 | @li wxMetafile | |
80 | @li wxPalette | |
81 | @li wxPen | |
82 | @li wxRegion | |
83 | @li wxString | |
84 | @li wxVariant | |
85 | @li wxVariantData | |
36c9828f | 86 | |
72844950 BP |
87 | Note that the list above reports the objects which are reference counted in all |
88 | ports of wxWidgets; some ports may use this technique also for other classes. | |
36c9828f | 89 | |
831e1028 BP |
90 | All the objects implement a function @b IsOk() to test if they are referencing |
91 | valid data; when the objects are in uninitialized state, you can only use the | |
92 | @b IsOk() getter; trying to call any other getter, e.g. wxBrush::GetStyle() on | |
93 | the ::wxNullBrush object, will result in an assert failure in debug builds. | |
f0a9a84c | 94 | |
36c9828f | 95 | |
72844950 | 96 | @section overview_refcount_object Making Your Own Reference Counted Class |
36c9828f | 97 | |
831e1028 BP |
98 | Reference counting can be implemented easily using wxObject or using the |
99 | intermediate wxRefCounter class directly. Alternatively, you can also use the | |
100 | wxObjectDataPtr<T> template. | |
36c9828f | 101 | |
831e1028 BP |
102 | First, derive a new class from wxRefCounter (or wxObjectRefData when using a |
103 | wxObject derived class) and put the memory-consuming data in it. | |
36c9828f | 104 | |
7442b5ee | 105 | Then derive a new class from wxObject and implement there the public interface |
72844950 | 106 | which will be seen by the user of your class. You'll probably want to add a |
7442b5ee | 107 | function to your class which does the cast from wxObjectRefData to your |
72844950 | 108 | class-specific shared data. For example: |
36c9828f | 109 | |
72844950 BP |
110 | @code |
111 | MyClassRefData* GetData() const | |
112 | { | |
113 | return wx_static_cast(MyClassRefData*, m_refData); | |
114 | } | |
115 | @endcode | |
36c9828f | 116 | |
72844950 BP |
117 | In fact, any time you need to read the data from your wxObject-derived class, |
118 | you will need to call this function. | |
36c9828f | 119 | |
72844950 | 120 | @note Any time you need to actually modify the data placed inside your wxObject |
3ed3a1c8 | 121 | derived class, you must first call the wxObject::UnShare() function to ensure |
72844950 BP |
122 | that the modifications won't affect other instances which are eventually |
123 | sharing your object's data. | |
36c9828f | 124 | |
72844950 | 125 | */ |