X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/451fdf7dd08824906b509282f87ce137c3c2c7ec..e18e78a7cc106a75e5228c51edd982436682633d:/docs/doxygen/overviews/refcount.h diff --git a/docs/doxygen/overviews/refcount.h b/docs/doxygen/overviews/refcount.h index 08f23649d6..48a2bf1bb7 100644 --- a/docs/doxygen/overviews/refcount.h +++ b/docs/doxygen/overviews/refcount.h @@ -1,121 +1,128 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: trefcount +// Name: refcount.h // Purpose: topic overview // Author: wxWidgets team // RCS-ID: $Id$ // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// -/*! +/** - @page trefcount_overview Reference counting +@page overview_refcount Reference Counting - @ref refcount_overview - @ref refcountequality_overview - @ref refcountdestruct_overview - @ref refcountlist_overview - @ref object_overview +@li @ref overview_refcount_ignore +@li @ref overview_refcount_equality +@li @ref overview_refcount_destruct +@li @ref overview_refcount_list +@li @ref overview_refcount_object - @section refcount Why you shouldn't care about it +
- Many wxWidgets objects use a technique known as @e reference counting, also known - as @e copy on write (COW). - This means that when an object is assigned to another, no copying really takes place: - only the reference count on the shared object data is incremented and both objects - share the same data (a very fast operation). - But as soon as one of the two (or more) objects is modified, the data has to be - copied because the changes to one of the objects shouldn't be seen in the - others. As data copying only happens when the object is written to, this is - known as COW. - What is important to understand is that all this happens absolutely - transparently to the class users and that whether an object is shared or not - is not seen from the outside of the class - in any case, the result of any - operation on it is the same. - @section refcountequality Object comparison +@section overview_refcount_ignore Why You Shouldn't Care About It - The == and != operators of @ref refcountlist_overview - always do a @c deep comparison. - This means that the equality operator will return @true if two objects are - identic and not only if they share the same data. - Note that wxWidgets follows the @e STL philosophy: when a comparison operator cannot - be implemented efficiently (like for e.g. wxImage's == operator which would need to - compare pixel-by-pixel the entire image's data), it's not implemented at all. - That's why not all reference-counted wxWidgets classes provide comparison operators. - Also note that if you only need to do a @c shallow comparison between two - #wxObject-derived classes, you should not use the == and != operators - but rather the wxObject::IsSameAs function. +Many wxWidgets objects use a technique known as reference counting, +also known as copy on write (COW). This means that when an object is +assigned to another, no copying really takes place. Only the reference count on +the shared object data is incremented and both objects share the same data (a +very fast operation). +But as soon as one of the two (or more) objects is modified, the data has to be +copied because the changes to one of the objects shouldn't be seen in the +others. As data copying only happens when the object is written to, this is +known as COW. - @section refcountdestruct Object destruction +What is important to understand is that all this happens absolutely +transparently to the class users and that whether an object is shared or not is +not seen from the outside of the class - in any case, the result of any +operation on it is the same. - When a COW object destructor is called, it may not delete the data: if it's shared, - the destructor will just decrement the shared data's reference count without destroying it. - Only when the destructor of the last object owning the data is called, the data is really - destroyed. As for all other COW-things, this happens transparently to the class users so - that you shouldn't care about it. +@section overview_refcount_equality Object Comparison - @section refcountlist List of reference-counted wxWidgets classes +The == and != operators of the reference counted classes always do a @c deep +comparison. This means that the equality operator will return @true if two +objects are identical and not only if they share the same data. - The following classes in wxWidgets have efficient (i.e. fast) assignment operators - and copy constructors since they are reference-counted: - #wxAcceleratorTable +Note that wxWidgets follows the STL philosophy: when a comparison +operator can not be implemented efficiently (like for e.g. wxImage's == +operator which would need to compare the entire image's data, pixel-by-pixel), +it's not implemented at all. That's why not all reference counted classes +provide comparison operators. - #wxAnimation +Also note that if you only need to do a @c shallow comparison between two +wxObject derived classes, you should not use the == and != operators but +rather the wxObject::IsSameAs() function. - #wxBitmap - #wxBrush +@section overview_refcount_destruct Object Destruction - #wxCursor +When a COW object destructor is called, it may not delete the data: if it's +shared, the destructor will just decrement the shared data's reference count +without destroying it. Only when the destructor of the last object owning the +data is called, the data is really destroyed. Just like all other COW-things, +this happens transparently to the class users so that you shouldn't care about +it. - #wxFont - #wxIcon +@section overview_refcount_list List of Reference Counted Classes - #wxImage +The following classes in wxWidgets have efficient (i.e. fast) assignment +operators and copy constructors since they are reference-counted: - #wxMetafile +@li wxAcceleratorTable +@li wxAnimation +@li wxBitmap +@li wxBrush +@li wxCursor +@li wxFont +@li wxIcon +@li wxImage +@li wxMetafile +@li wxPalette +@li wxPen +@li wxRegion +@li wxString +@li wxVariant +@li wxVariantData - #wxPalette +Note that the list above reports the objects which are reference counted in all +ports of wxWidgets; some ports may use this technique also for other classes. - #wxPen +All the objects implement a function IsOk() to test if they are referencing valid +data; when the objects are in uninitialized state, you can only use the IsOk() getter; +trying to call any other getter, e.g. wxBrush::GetStyle() on the ::wxNullBrush object, +will result in an assert failure in debug builds. - #wxRegion - #wxString +@section overview_refcount_object Making Your Own Reference Counted Class - #wxVariant +Reference counting can be implemented easily using wxObject and wxObjectRefData +classes. Alternatively, you can also use the wxObjectDataPtr template. - #wxVariantData - Note that the list above reports the objects which are reference-counted in all ports of - wxWidgets; some ports may use this tecnique also for other classes. +First, derive a new class from wxObjectRefData and put there the +memory-consuming data. - @section wxobjectoverview Make your own reference-counted class +Then derive a new class from wxObject and implement there the public interface +which will be seen by the user of your class. You'll probably want to add a +function to your class which does the cast from wxObjectRefData to your +class-specific shared data. For example: - Reference counting can be implemented easily using #wxObject - and #wxObjectRefData classes. Alternatively, you - can also use the #wxObjectDataPtrT template. - First, derive a new class from #wxObjectRefData and - put there the memory-consuming data. - Then derive a new class from #wxObject and implement there - the public interface which will be seen by the user of your class. - You'll probably want to add a function to your class which does the cast from - #wxObjectRefData to your class-specific shared data; e.g.: +@code +MyClassRefData* GetData() const +{ + return wx_static_cast(MyClassRefData*, m_refData); +} +@endcode - @code - MyClassRefData *GetData() const { return wx_static_cast(MyClassRefData*, m_refData); } - @endcode +In fact, any time you need to read the data from your wxObject-derived class, +you will need to call this function. - in fact, all times you'll need to read the data from your wxObject-derived class, - you'll need to call such function. - Very important, all times you need to actually modify the data placed inside your - wxObject-derived class, you must first call the wxObject::UnShare - function to be sure that the modifications won't affect other instances which are - eventually sharing your object's data. - - */ +@note Any time you need to actually modify the data placed inside your wxObject +derived class, you must first call the wxObject::UnShare function to ensure +that the modifications won't affect other instances which are eventually +sharing your object's data. +*/