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