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