[190] | 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"><!--
|
---|
| 8 | fn { margin-left: 1cm; text-indent: -1cm; }
|
---|
| 9 | a:link { color: #004faf; text-decoration: none }
|
---|
| 10 | a:visited { color: #672967; text-decoration: none }
|
---|
| 11 | body { 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 Classes</font></a>
|
---|
| 23 | | <a href="mainclasses.html">
|
---|
| 24 | <font color="#004faf">Main 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 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
|
---|
| 38 | to 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
|
---|
| 59 | contains a reference count and the data.
|
---|
| 60 | <p> When a shared object is created, it sets the reference count to 1. The
|
---|
| 61 | reference count is incremented whenever a new object references the
|
---|
| 62 | shared data, and decremented when the object dereferences the shared
|
---|
| 63 | data. The shared data is deleted when the reference count becomes
|
---|
| 64 | zero.
|
---|
| 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
|
---|
| 67 | object. We usually speak about <em>deep</em> and <em>shallow</em> copies. A deep
|
---|
| 68 | copy implies duplicating an object. A shallow copy is a reference
|
---|
| 69 | copy, i.e. just a pointer to a shared data block. Making a deep copy
|
---|
| 70 | can be expensive in terms of memory and CPU. Making a shallow copy is
|
---|
| 71 | very fast, because it only involves setting a pointer and incrementing
|
---|
| 72 | the reference count.
|
---|
| 73 | <p> Object assignment (with operator=()) for implicitly and explicitly
|
---|
| 74 | shared objects is implemented using shallow copies. A deep copy can be
|
---|
| 75 | made 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
|
---|
| 77 | data unnecessarily, which results in lower memory use and less copying
|
---|
| 78 | of data. Objects can easily be assigned, sent as function arguments,
|
---|
| 79 | and returned from functions.
|
---|
| 80 | <p> Now comes the distinction between <em>explicit</em> and <em>implicit</em> sharing.
|
---|
| 81 | Explicit sharing means that the programmer must be aware of the fact
|
---|
| 82 | that objects share common data. Implicit sharing means that the
|
---|
| 83 | sharing mechanism takes place behind the scenes and the programmer
|
---|
| 84 | does 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.
|
---|
| 88 | Example:
|
---|
| 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
|
---|
| 103 | block (the reference count becomes zero), sets <tt>a</tt>'s shared block to
|
---|
| 104 | point 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,
|
---|
| 106 | because <tt>a</tt> and <tt>b</tt> refer to the same data block. This is the
|
---|
| 107 | difference between explicit and implicit sharing (explained below).
|
---|
| 108 | <p> The <tt>a</tt> object detaches from the common data on line 6. Detaching
|
---|
| 109 | means that the shared data is copied to make sure that an object has
|
---|
| 110 | its own private data. Therefore, modifying <tt>a</tt> on line 7 does not
|
---|
| 111 | affect <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>,
|
---|
| 113 | so 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
|
---|
| 117 | if the object is about to change and the reference count is greater
|
---|
| 118 | than one. (This is often called "copy-on-write".) Explicit sharing
|
---|
| 119 | leaves this job to the programmer. If an explicitly shared object is
|
---|
| 120 | not detached, changing an object will change all other objects that
|
---|
| 121 | refer to the same data.
|
---|
| 122 | <p> Implicit sharing optimizes memory use and copying of data without
|
---|
| 123 | this side effect. So why didn't we implement implicit sharing for all
|
---|
| 124 | shared classes? The answer is that a class that allows direct access
|
---|
| 125 | to its internal data (for efficiency reasons), like <a href="qbytearray.html">QByteArray</a>, cannot
|
---|
| 126 | be implicitly shared, because it can be changed without letting
|
---|
| 127 | QByteArray know.
|
---|
| 128 | <p> An implicitly shared class has total control of its internal data. In
|
---|
| 129 | any member functions that modify its data, it automatically detaches
|
---|
| 130 | before modifying the data.
|
---|
| 131 | <p> The <a href="qpen.html">QPen</a> class, which uses implicit sharing, detaches from the shared
|
---|
| 132 | data 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->style = s; // set the style member
|
---|
| 139 | }
|
---|
| 140 |
|
---|
| 141 | void QPen::detach()
|
---|
| 142 | {
|
---|
| 143 | if ( data->count != 1 ) // only if >1 reference
|
---|
| 144 | *this = copy();
|
---|
| 145 | }
|
---|
| 146 | </pre>
|
---|
| 147 |
|
---|
| 148 | <p> This is clearly not possible for QByteArray, because the programmer
|
---|
| 149 | can 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
|
---|
| 158 | become 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
|
---|
| 162 | explicitly 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<type></a>
|
---|
| 168 | </ul>
|
---|
| 169 | <p> These classes have a detach() function that can be called if you want
|
---|
| 170 | your object to get a private copy of the shared data. They also have a
|
---|
| 171 | copy() 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
|
---|
| 173 | copy().
|
---|
| 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
|
---|
| 198 | about to be changed. The programmer will not even notice that the
|
---|
| 199 | objects are shared. Thus you should treat separate instances of them
|
---|
| 200 | as separate objects. They will always behave as separate objects but
|
---|
| 201 | with the added benefit of sharing data whenever possible. For this
|
---|
| 202 | reason, you can pass instances of these classes as arguments to
|
---|
| 203 | functions 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>( &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
|
---|
| 216 | called for <tt>p2</tt>, because painting a pixmap will modify it. The same
|
---|
| 217 | also 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
|
---|
| 224 | inherited from <a href="qbytearray.html">QByteArray</a>, such as data(), employ explicit sharing, while
|
---|
| 225 | those 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.
|
---|
| 227 | We 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 © 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>
|
---|