source: trunk/doc/html/shclass.html@ 190

Last change on this file since 190 was 190, checked in by rudi, 14 years ago

reference documentation added

File size: 11.6 KB
Line 
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/doc/shclass.doc:36 -->
3<html>
4<head>
5<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
6<title>Shared Classes</title>
7<style type="text/css"><!--
8fn { margin-left: 1cm; text-indent: -1cm; }
9a:link { color: #004faf; text-decoration: none }
10a:visited { color: #672967; text-decoration: none }
11body { background: #ffffff; color: black; }
12--></style>
13</head>
14<body>
15
16<table border="0" cellpadding="0" cellspacing="0" width="100%">
17<tr bgcolor="#E5E5E5">
18<td valign=center>
19 <a href="index.html">
20<font color="#004faf">Home</font></a>
21 | <a href="classes.html">
22<font color="#004faf">All&nbsp;Classes</font></a>
23 | <a href="mainclasses.html">
24<font color="#004faf">Main&nbsp;Classes</font></a>
25 | <a href="annotated.html">
26<font color="#004faf">Annotated</font></a>
27 | <a href="groups.html">
28<font color="#004faf">Grouped&nbsp;Classes</font></a>
29 | <a href="functions.html">
30<font color="#004faf">Functions</font></a>
31</td>
32<td align="right" valign="center"><img src="logo32.png" align="right" width="64" height="32" border="0"></td></tr></table><h1 align=center>Shared Classes</h1>
33
34
35
36<p> <!-- index reference counting --><a name="reference-counting"></a><!-- index implicit sharing --><a name="implicit-sharing"></a><!-- index explicit sharing --><a name="explicit-sharing"></a><!-- index implicitly shared --><a name="implicitly-shared"></a><!-- index explicitly shared --><a name="explicitly-shared"></a><!-- index explicit sharing --><a name="explicit-sharing"></a><!-- index shared implicitly --><a name="shared-implicitly"></a><!-- index shared explicitly --><a name="shared-explicitly"></a>
37<p> Many C++ classes in Qt use <em>explicit</em> and <em>implicit</em> data sharing
38to maximize resource usage and minimize copying of data.
39<p> <!-- toc -->
40<ul>
41<li><a href="#1"> Overview
42</a>
43<li><a href="#2"> A QByteArray Example
44</a>
45<li><a href="#3"> Explicit vs. Implicit Sharing
46</a>
47<li><a href="#4"> Explicitly Shared Classes
48</a>
49<li><a href="#5"> Implicitly Shared Classes
50</a>
51<li><a href="#6"> QCString: implicit or explicit?
52</a>
53</ul>
54<!-- endtoc -->
55
56<p> <h2> Overview
57</h2>
58<a name="1"></a><p> A shared class consists of a pointer to a shared data block that
59contains a reference count and the data.
60<p> When a shared object is created, it sets the reference count to 1. The
61reference count is incremented whenever a new object references the
62shared data, and decremented when the object dereferences the shared
63data. The shared data is deleted when the reference count becomes
64zero.
65<p> <!-- index deep copy --><a name="deep-copy"></a><!-- index shallow copy --><a name="shallow-copy"></a>
66<p> When dealing with shared objects, there are two ways of copying an
67object. We usually speak about <em>deep</em> and <em>shallow</em> copies. A deep
68copy implies duplicating an object. A shallow copy is a reference
69copy, i.e. just a pointer to a shared data block. Making a deep copy
70can be expensive in terms of memory and CPU. Making a shallow copy is
71very fast, because it only involves setting a pointer and incrementing
72the reference count.
73<p> Object assignment (with operator=()) for implicitly and explicitly
74shared objects is implemented using shallow copies. A deep copy can be
75made by calling a copy() function or by using <a href="qdeepcopy.html">QDeepCopy</a>.
76<p> The benefit of sharing is that a program does not need to duplicate
77data unnecessarily, which results in lower memory use and less copying
78of data. Objects can easily be assigned, sent as function arguments,
79and returned from functions.
80<p> Now comes the distinction between <em>explicit</em> and <em>implicit</em> sharing.
81Explicit sharing means that the programmer must be aware of the fact
82that objects share common data. Implicit sharing means that the
83sharing mechanism takes place behind the scenes and the programmer
84does not need to worry about it.
85<p> <h2> A <a href="qbytearray.html">QByteArray</a> Example
86</h2>
87<a name="2"></a><p> QByteArray is an example of a shared class that uses explicit sharing.
88Example:
89<pre>
90 //Line a= b= c=
91 <a href="qbytearray.html">QByteArray</a> a(3),b(2) // 1: {?,?,?} {?,?}
92 b[0] = 12; b[1] = 34; // 2: {?,?,?} {12,34}
93 a = b; // 3: {12,34} {12,34}
94 a[1] = 56; // 4: {12,56} {12,56}
95 <a href="qbytearray.html">QByteArray</a> c = a; // 5: {12,56} {12,56} {12,56}
96 a.<a href="qmemarray.html#detach">detach</a>(); // 6: {12,56} {12,56} {12,56}
97 a[1] = 78; // 7: {12,78} {12,56} {12,56}
98 b = a.<a href="qmemarray.html#copy">copy</a>(); // 8: {12,78} {12,78} {12,56}
99 a[1] = 90; // 9: {12,90} {12,78} {12,56}
100</pre>
101
102<p> The assignment <tt>a = b</tt> on line 3 throws away <tt>a</tt>'s original shared
103block (the reference count becomes zero), sets <tt>a</tt>'s shared block to
104point to <tt>b</tt>'s shared block and increments the reference count.
105<p> On line 4, the contents of <tt>a</tt> is modified. <tt>b</tt> is also modified,
106because <tt>a</tt> and <tt>b</tt> refer to the same data block. This is the
107difference between explicit and implicit sharing (explained below).
108<p> The <tt>a</tt> object detaches from the common data on line 6. Detaching
109means that the shared data is copied to make sure that an object has
110its own private data. Therefore, modifying <tt>a</tt> on line 7 does not
111affect <tt>b</tt> or <tt>c</tt>.
112<p> Finally, on line 8 we make a deep copy of <tt>a</tt> and assign it to <tt>b</tt>,
113so that when <tt>a</tt> is modified on line 9, <tt>b</tt> remains unchanged.
114<p> <h2> Explicit vs. Implicit Sharing
115</h2>
116<a name="3"></a><p> Implicit sharing automatically detaches the object from a shared block
117if the object is about to change and the reference count is greater
118than one. (This is often called "copy-on-write".) Explicit sharing
119leaves this job to the programmer. If an explicitly shared object is
120not detached, changing an object will change all other objects that
121refer to the same data.
122<p> Implicit sharing optimizes memory use and copying of data without
123this side effect. So why didn't we implement implicit sharing for all
124shared classes? The answer is that a class that allows direct access
125to its internal data (for efficiency reasons), like <a href="qbytearray.html">QByteArray</a>, cannot
126be implicitly shared, because it can be changed without letting
127QByteArray know.
128<p> An implicitly shared class has total control of its internal data. In
129any member functions that modify its data, it automatically detaches
130before modifying the data.
131<p> The <a href="qpen.html">QPen</a> class, which uses implicit sharing, detaches from the shared
132data in all member functions that change the internal data.
133<p> Code fragment:
134<pre>
135 void QPen::setStyle( PenStyle s )
136 {
137 detach(); // detach from common data
138 data-&gt;style = s; // set the style member
139 }
140
141 void QPen::detach()
142 {
143 if ( data-&gt;count != 1 ) // only if &gt;1 reference
144 *this = copy();
145 }
146</pre>
147
148<p> This is clearly not possible for QByteArray, because the programmer
149can do the following:
150<p> <pre>
151 <a href="qbytearray.html">QByteArray</a> array( 10 );
152 array.<a href="qmemarray.html#fill">fill</a>( 'a' );
153 array[0] = 'f'; // will modify array
154 array.<a href="qmemarray.html#data">data</a>()[1] = 'i'; // will modify array
155</pre>
156
157<p> If we monitor changes in a <a href="qbytearray.html">QByteArray</a>, the QByteArray class would
158become unacceptably slow.
159<p> <h2> Explicitly Shared Classes
160</h2>
161<a name="4"></a><p> All classes that are instances of the <a href="qmemarray.html">QMemArray</a> template class are
162explicitly shared:
163<p> <ul>
164<li> <a href="qbitarray.html">QBitArray</a>
165<li> <a href="qpointarray.html">QPointArray</a>
166<li> <a href="qbytearray.html">QByteArray</a>
167<li> Any other instantiation of <a href="qmemarray.html">QMemArray&lt;type&gt;</a>
168</ul>
169<p> These classes have a detach() function that can be called if you want
170your object to get a private copy of the shared data. They also have a
171copy() function that returns a deep copy with a reference count of 1.
172<p> The same is true for <a href="qimage.html">QImage</a>, which does not inherit QMemArray. <a href="qmovie.html">QMovie</a> is also explicitly shared, but it does not support detach() or
173copy().
174<p> <h2> Implicitly Shared Classes
175</h2>
176<a name="5"></a><p> The Qt classes that are implicitly shared are:
177<ul>
178<li> <a href="qbitmap.html">QBitmap</a>
179<li> <a href="qbrush.html">QBrush</a>
180<li> <a href="qcursor.html">QCursor</a>
181<li> <a href="qfont.html">QFont</a>
182<li> <a href="qfontinfo.html">QFontInfo</a>
183<li> <a href="qfontmetrics.html">QFontMetrics</a>
184<li> <a href="qiconset.html">QIconSet</a>
185<li> <a href="qmap.html">QMap</a>
186<li> <a href="qpalette.html">QPalette</a>
187<li> <a href="qpen.html">QPen</a>
188<li> <a href="qpicture.html">QPicture</a>
189<li> <a href="qpixmap.html">QPixmap</a>
190<li> <a href="qregion.html">QRegion</a>
191<li> <a href="qregexp.html">QRegExp</a>
192<li> <a href="qstring.html">QString</a>
193<li> <a href="qstringlist.html">QStringList</a>
194<li> <a href="qvaluelist.html">QValueList</a>
195<li> <a href="qvaluestack.html">QValueStack</a>
196</ul>
197<p> These classes automatically detach from common data if an object is
198about to be changed. The programmer will not even notice that the
199objects are shared. Thus you should treat separate instances of them
200as separate objects. They will always behave as separate objects but
201with the added benefit of sharing data whenever possible. For this
202reason, you can pass instances of these classes as arguments to
203functions by value without concern for the copying overhead.
204<p> Example:
205<pre>
206 <a href="qpixmap.html">QPixmap</a> p1, p2;
207 p1.<a href="qpixmap.html#load">load</a>( "image.bmp" );
208 p2 = p1; // p1 and p2 share data
209 <a href="qpainter.html">QPainter</a> paint;
210 paint.<a href="qpainter.html#begin">begin</a>( &amp;p2 ); // cuts p2 loose from p1
211 paint.<a href="qpainter.html#drawText">drawText</a>( 0,50, "Hi" );
212 paint.<a href="qpainter.html#end">end</a>();
213</pre>
214
215<p> In this example, <tt>p1</tt> and <tt>p2</tt> share data until <a href="qpainter.html#begin">QPainter::begin</a>() is
216called for <tt>p2</tt>, because painting a pixmap will modify it. The same
217also happens if anything is <a href="qimage.html#bitBlt">bitBlt()</a>'ed into
218<tt>p2</tt>.
219<p> <b>Warning:</b> Do not copy an implicitly shared container (<a href="qmap.html">QMap</a>,
220<a href="qvaluevector.html">QValueVector</a>, etc.) while you are iterating over it.
221<p> <h2> QCString: implicit or explicit?
222</h2>
223<a name="6"></a><p> <a href="qcstring.html">QCString</a> uses a mixture of implicit and explicit sharing. Functions
224inherited from <a href="qbytearray.html">QByteArray</a>, such as data(), employ explicit sharing, while
225those only in <a href="qcstring.html">QCString</a> detach automatically. Thus, QCString is rather an
226"experts only" class, provided mainly to ease porting from Qt 1.x to Qt 2.0.
227We recommend that you use <a href="qstring.html">QString</a>, a purely implicitly shared class.
228<p>
229<!-- eof -->
230<p><address><hr><div align=center>
231<table width=100% cellspacing=0 border=0><tr>
232<td>Copyright &copy; 2007
233<a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a>
234<td align=right><div align=right>Qt 3.3.8</div>
235</table></div></address></body>
236</html>
Note: See TracBrowser for help on using the repository browser.