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