File: overview_refcount.html

package info (click to toggle)
wxpython3.0 3.0.2.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 482,760 kB
  • ctags: 518,293
  • sloc: cpp: 2,127,226; python: 294,045; makefile: 51,942; ansic: 19,033; sh: 3,013; xml: 1,629; perl: 17
file content (120 lines) | stat: -rw-r--r-- 12,520 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>wxWidgets: Reference Counting</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="extra_stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="page_container">
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0" style="width: 100%;">
 <tbody>
 <tr>
  <td id="projectlogo">
    <a href="http://www.wxwidgets.org/" target="_new">
      <img alt="wxWidgets" src="logo.png"/>
    </a>
  </td>
  <td style="padding-left: 0.5em; text-align: right;">
   <span id="projectnumber">Version: 3.0.2</span>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- Generated by Doxygen 1.8.2 -->
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li class="current"><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="modules.html"><span>Categories</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="index.html">Documentation</a></li><li class="navelem"><a class="el" href="page_topics.html">Programming Guides</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Reference Counting </div>  </div>
</div><!--header-->
<div class="contents">
<div class="toc"><h3>Table of Contents</h3>
<ul><li class="level1"><a href="#overview_refcount_equality">Object Comparison</a></li>
<li class="level1"><a href="#overview_refcount_destruct">Object Destruction</a></li>
<li class="level1"><a href="#overview_refcount_list">List of Reference Counted Classes</a></li>
<li class="level1"><a href="#overview_refcount_object">Making Your Own Reference Counted Class</a></li>
</ul>
</div>
<div class="textblock"><p>Many wxWidgets objects use a technique known as <em>reference counting</em>, also known as <em>copy on write</em> (COW).</p>
<p>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).</p>
<p>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.</p>
<p>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.</p>
<h1><a class="anchor" id="overview_refcount_equality"></a>
Object Comparison</h1>
<p>The == and != operators of <a class="el" href="overview_refcount.html#overview_refcount_list">the reference counted classes</a> always do a <em>deep comparison</em>. This means that the equality operator will return <span class="literal">true</span> if two objects are identical and not only if they share the same data.</p>
<p>Note that wxWidgets follows the <em>STL philosophy</em>: when a comparison operator cannot be implemented efficiently (like for e.g. <a class="el" href="classwx_image.html" title="This class encapsulates a platform-independent image.">wxImage</a>'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.</p>
<p>Also note that if you only need to do a <code>shallow</code> comparison between two <a class="el" href="classwx_object.html" title="This is the root class of many of the wxWidgets classes.">wxObject</a> derived classes, you should not use the == and != operators but rather the <a class="el" href="classwx_object.html#a80a1a3fda7b14396a9ddd3d7a46a88bd" title="Returns true if this object has the same data pointer as obj.">wxObject::IsSameAs()</a> function.</p>
<h1><a class="anchor" id="overview_refcount_destruct"></a>
Object Destruction</h1>
<p>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.</p>
<h1><a class="anchor" id="overview_refcount_list"></a>
List of Reference Counted Classes</h1>
<p>The following classes in wxWidgets have efficient (i.e. fast) assignment operators and copy constructors since they are reference-counted:</p>
<ul>
<li><a class="el" href="classwx_accelerator_table.html" title="An accelerator table allows the application to specify a table of keyboard shortcuts for menu or butt...">wxAcceleratorTable</a> </li>
<li><a class="el" href="classwx_animation.html" title="This class encapsulates the concept of a platform-dependent animation.">wxAnimation</a> </li>
<li><a class="el" href="classwx_bitmap.html" title="This class encapsulates the concept of a platform-dependent bitmap, either monochrome or colour or co...">wxBitmap</a> </li>
<li><a class="el" href="classwx_brush.html" title="A brush is a drawing tool for filling in areas.">wxBrush</a> </li>
<li><a class="el" href="classwx_cursor.html" title="A cursor is a small bitmap usually used for denoting where the mouse pointer is, with a picture that ...">wxCursor</a> </li>
<li><a class="el" href="classwx_font.html" title="A font is an object which determines the appearance of text.">wxFont</a> </li>
<li><a class="el" href="classwx_graphics_brush.html" title="A wxGraphicsBrush is a native representation of a brush.">wxGraphicsBrush</a> </li>
<li><a class="el" href="classwx_graphics_context.html" title="A wxGraphicsContext instance is the object that is drawn upon.">wxGraphicsContext</a> </li>
<li><a class="el" href="classwx_graphics_font.html" title="A wxGraphicsFont is a native representation of a font.">wxGraphicsFont</a> </li>
<li><a class="el" href="classwx_graphics_matrix.html" title="A wxGraphicsMatrix is a native representation of an affine matrix.">wxGraphicsMatrix</a> </li>
<li><a class="el" href="classwx_graphics_path.html" title="A wxGraphicsPath is a native representation of a geometric path.">wxGraphicsPath</a> </li>
<li><a class="el" href="classwx_graphics_pen.html" title="A wxGraphicsPen is a native representation of a pen.">wxGraphicsPen</a> </li>
<li><a class="el" href="classwx_icon.html" title="An icon is a small rectangular bitmap usually used for denoting a minimized application.">wxIcon</a> </li>
<li><a class="el" href="classwx_image.html" title="This class encapsulates a platform-independent image.">wxImage</a> </li>
<li><a class="el" href="classwx_metafile.html" title="A wxMetafile represents the MS Windows metafile object, so metafile operations have no effect in X...">wxMetafile</a> </li>
<li><a class="el" href="classwx_palette.html" title="A palette is a table that maps pixel values to RGB colours.">wxPalette</a> </li>
<li><a class="el" href="classwx_pen.html" title="A pen is a drawing tool for drawing outlines.">wxPen</a> </li>
<li><a class="el" href="classwx_region.html" title="A wxRegion represents a simple or complex region on a device context or window.">wxRegion</a> </li>
<li><a class="el" href="classwx_string.html" title="String class for passing textual data to or receiving it from wxWidgets.">wxString</a> </li>
<li><a class="el" href="classwx_variant.html" title="The wxVariant class represents a container for any type.">wxVariant</a> </li>
<li><a class="el" href="classwx_variant_data.html" title="The wxVariantData class is used to implement a new type for wxVariant.">wxVariantData</a></li>
</ul>
<p>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.</p>
<p>All the objects implement a function <b>IsOk()</b> to test if they are referencing valid data; when the objects are in uninitialized state, you can only use the <b>IsOk()</b> getter; trying to call any other getter, e.g. <a class="el" href="classwx_brush.html#aa417c1eaa67e4476652fbf949a46c26a" title="Returns the brush style, one of the wxBrushStyle values.">wxBrush::GetStyle()</a> on the <a class="el" href="brush_8h.html#a9919a44109f2c6091c71aece17ca7013" title="An empty brush.">wxNullBrush</a> object, will result in an assert failure in debug builds.</p>
<h1><a class="anchor" id="overview_refcount_object"></a>
Making Your Own Reference Counted Class</h1>
<p>Reference counting can be implemented easily using <a class="el" href="classwx_object.html" title="This is the root class of many of the wxWidgets classes.">wxObject</a> or using the intermediate <a class="el" href="classwx_ref_counter.html" title="This class is used to manage reference-counting providing a simple interface and a counter...">wxRefCounter</a> class directly. Alternatively, you can also use the <a class="el" href="classwx_object_data_ptr_3_01_t_01_4.html" title="This is an helper template class primarily written to avoid memory leaks because of missing calls to ...">wxObjectDataPtr&lt;T&gt;</a> template.</p>
<p>First, derive a new class from <a class="el" href="classwx_ref_counter.html" title="This class is used to manage reference-counting providing a simple interface and a counter...">wxRefCounter</a> (or <a class="el" href="classwx_object_ref_data.html" title="This class is just a typedef to wxRefCounter and is used by wxObject.">wxObjectRefData</a> when using a <a class="el" href="classwx_object.html" title="This is the root class of many of the wxWidgets classes.">wxObject</a> derived class) and put the memory-consuming data in it.</p>
<p>Then derive a new class from <a class="el" href="classwx_object.html" title="This is the root class of many of the wxWidgets classes.">wxObject</a> 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 <a class="el" href="classwx_object_ref_data.html" title="This class is just a typedef to wxRefCounter and is used by wxObject.">wxObjectRefData</a> to your class-specific shared data. For example:</p>
<div class="fragment"><div class="line">MyClassRefData* GetData()<span class="keyword"> const</span></div>
<div class="line"><span class="keyword"></span>{</div>
<div class="line">    <span class="keywordflow">return</span> <a class="code" href="group__group__funcmacro__rtti.html#gaa3a4a52303d4a1fa3d3346e762638c64" title="Same as static_cast&lt;T&gt;(x) if the compiler supports static cast or (T)x for old compilers.">wx_static_cast</a>(MyClassRefData*, m_refData);</div>
<div class="line">}</div>
</div><!-- fragment --><p>In fact, any time you need to read the data from your wxObject-derived class, you will need to call this function.</p>
<dl class="section note"><dt>Note</dt><dd>Any time you need to actually modify the data placed inside your <a class="el" href="classwx_object.html" title="This is the root class of many of the wxWidgets classes.">wxObject</a> derived class, you must first call the <a class="el" href="classwx_object.html#a74b40e42d19a4b9e9bec0b57d62a5725" title="This is the same of AllocExclusive() but this method is public.">wxObject::UnShare()</a> function to ensure that the modifications won't affect other instances which are eventually sharing your object's data. </dd></dl>
</div></div><!-- contents -->

<address class="footer">
	<small>
		Generated on Thu Nov 27 2014 13:46:42 for wxWidgets by <a href="http://www.doxygen.org/index.html" target="_new">Doxygen</a> 1.8.2
	</small>
</address>
<script src="wxwidgets.js" type="text/javascript"></script>
</div><!-- #page_container -->
</body>
</html>