diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:24:15 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:24:15 -0500 |
commit | bd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch) | |
tree | 7a520322212d48ebcb9fbe1087e7fca28b76185c /doc/html/shclass.html | |
download | qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip |
Add Qt3 development HEAD version
Diffstat (limited to 'doc/html/shclass.html')
-rw-r--r-- | doc/html/shclass.html | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/doc/html/shclass.html b/doc/html/shclass.html new file mode 100644 index 0000000..2f64ecf --- /dev/null +++ b/doc/html/shclass.html @@ -0,0 +1,236 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/doc/shclass.doc:36 --> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>Shared Classes</title> +<style type="text/css"><!-- +fn { margin-left: 1cm; text-indent: -1cm; } +a:link { color: #004faf; text-decoration: none } +a:visited { color: #672967; text-decoration: none } +body { background: #ffffff; color: black; } +--></style> +</head> +<body> + +<table border="0" cellpadding="0" cellspacing="0" width="100%"> +<tr bgcolor="#E5E5E5"> +<td valign=center> + <a href="index.html"> +<font color="#004faf">Home</font></a> + | <a href="classes.html"> +<font color="#004faf">All Classes</font></a> + | <a href="mainclasses.html"> +<font color="#004faf">Main Classes</font></a> + | <a href="annotated.html"> +<font color="#004faf">Annotated</font></a> + | <a href="groups.html"> +<font color="#004faf">Grouped Classes</font></a> + | <a href="functions.html"> +<font color="#004faf">Functions</font></a> +</td> +<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> + + + +<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> +<p> Many C++ classes in Qt use <em>explicit</em> and <em>implicit</em> data sharing +to maximize resource usage and minimize copying of data. +<p> <!-- toc --> +<ul> +<li><a href="#1"> Overview +</a> +<li><a href="#2"> A QByteArray Example +</a> +<li><a href="#3"> Explicit vs. Implicit Sharing +</a> +<li><a href="#4"> Explicitly Shared Classes +</a> +<li><a href="#5"> Implicitly Shared Classes +</a> +<li><a href="#6"> QCString: implicit or explicit? +</a> +</ul> +<!-- endtoc --> + +<p> <h2> Overview +</h2> +<a name="1"></a><p> A shared class consists of a pointer to a shared data block that +contains a reference count and the data. +<p> When a shared object is created, it sets the reference count to 1. The +reference count is incremented whenever a new object references the +shared data, and decremented when the object dereferences the shared +data. The shared data is deleted when the reference count becomes +zero. +<p> <!-- index deep copy --><a name="deep-copy"></a><!-- index shallow copy --><a name="shallow-copy"></a> +<p> When dealing with shared objects, there are two ways of copying an +object. We usually speak about <em>deep</em> and <em>shallow</em> copies. A deep +copy implies duplicating an object. A shallow copy is a reference +copy, i.e. just a pointer to a shared data block. Making a deep copy +can be expensive in terms of memory and CPU. Making a shallow copy is +very fast, because it only involves setting a pointer and incrementing +the reference count. +<p> Object assignment (with operator=()) for implicitly and explicitly +shared objects is implemented using shallow copies. A deep copy can be +made by calling a copy() function or by using <a href="qdeepcopy.html">QDeepCopy</a>. +<p> The benefit of sharing is that a program does not need to duplicate +data unnecessarily, which results in lower memory use and less copying +of data. Objects can easily be assigned, sent as function arguments, +and returned from functions. +<p> Now comes the distinction between <em>explicit</em> and <em>implicit</em> sharing. +Explicit sharing means that the programmer must be aware of the fact +that objects share common data. Implicit sharing means that the +sharing mechanism takes place behind the scenes and the programmer +does not need to worry about it. +<p> <h2> A <a href="qbytearray.html">QByteArray</a> Example +</h2> +<a name="2"></a><p> QByteArray is an example of a shared class that uses explicit sharing. +Example: +<pre> + //Line a= b= c= + <a href="qbytearray.html">QByteArray</a> a(3),b(2) // 1: {?,?,?} {?,?} + b[0] = 12; b[1] = 34; // 2: {?,?,?} {12,34} + a = b; // 3: {12,34} {12,34} + a[1] = 56; // 4: {12,56} {12,56} + <a href="qbytearray.html">QByteArray</a> c = a; // 5: {12,56} {12,56} {12,56} + a.<a href="qmemarray.html#detach">detach</a>(); // 6: {12,56} {12,56} {12,56} + a[1] = 78; // 7: {12,78} {12,56} {12,56} + b = a.<a href="qmemarray.html#copy">copy</a>(); // 8: {12,78} {12,78} {12,56} + a[1] = 90; // 9: {12,90} {12,78} {12,56} +</pre> + +<p> The assignment <tt>a = b</tt> on line 3 throws away <tt>a</tt>'s original shared +block (the reference count becomes zero), sets <tt>a</tt>'s shared block to +point to <tt>b</tt>'s shared block and increments the reference count. +<p> On line 4, the contents of <tt>a</tt> is modified. <tt>b</tt> is also modified, +because <tt>a</tt> and <tt>b</tt> refer to the same data block. This is the +difference between explicit and implicit sharing (explained below). +<p> The <tt>a</tt> object detaches from the common data on line 6. Detaching +means that the shared data is copied to make sure that an object has +its own private data. Therefore, modifying <tt>a</tt> on line 7 does not +affect <tt>b</tt> or <tt>c</tt>. +<p> Finally, on line 8 we make a deep copy of <tt>a</tt> and assign it to <tt>b</tt>, +so that when <tt>a</tt> is modified on line 9, <tt>b</tt> remains unchanged. +<p> <h2> Explicit vs. Implicit Sharing +</h2> +<a name="3"></a><p> Implicit sharing automatically detaches the object from a shared block +if the object is about to change and the reference count is greater +than one. (This is often called "copy-on-write".) Explicit sharing +leaves this job to the programmer. If an explicitly shared object is +not detached, changing an object will change all other objects that +refer to the same data. +<p> Implicit sharing optimizes memory use and copying of data without +this side effect. So why didn't we implement implicit sharing for all +shared classes? The answer is that a class that allows direct access +to its internal data (for efficiency reasons), like <a href="qbytearray.html">QByteArray</a>, cannot +be implicitly shared, because it can be changed without letting +QByteArray know. +<p> An implicitly shared class has total control of its internal data. In +any member functions that modify its data, it automatically detaches +before modifying the data. +<p> The <a href="qpen.html">QPen</a> class, which uses implicit sharing, detaches from the shared +data in all member functions that change the internal data. +<p> Code fragment: +<pre> + void QPen::setStyle( PenStyle s ) + { + detach(); // detach from common data + data->style = s; // set the style member + } + + void QPen::detach() + { + if ( data->count != 1 ) // only if >1 reference + *this = copy(); + } +</pre> + +<p> This is clearly not possible for QByteArray, because the programmer +can do the following: +<p> <pre> + <a href="qbytearray.html">QByteArray</a> array( 10 ); + array.<a href="qmemarray.html#fill">fill</a>( 'a' ); + array[0] = 'f'; // will modify array + array.<a href="qmemarray.html#data">data</a>()[1] = 'i'; // will modify array +</pre> + +<p> If we monitor changes in a <a href="qbytearray.html">QByteArray</a>, the QByteArray class would +become unacceptably slow. +<p> <h2> Explicitly Shared Classes +</h2> +<a name="4"></a><p> All classes that are instances of the <a href="qmemarray.html">QMemArray</a> template class are +explicitly shared: +<p> <ul> +<li> <a href="qbitarray.html">QBitArray</a> +<li> <a href="qpointarray.html">QPointArray</a> +<li> <a href="qbytearray.html">QByteArray</a> +<li> Any other instantiation of <a href="qmemarray.html">QMemArray<type></a> +</ul> +<p> These classes have a detach() function that can be called if you want +your object to get a private copy of the shared data. They also have a +copy() function that returns a deep copy with a reference count of 1. +<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 +copy(). +<p> <h2> Implicitly Shared Classes +</h2> +<a name="5"></a><p> The Qt classes that are implicitly shared are: +<ul> +<li> <a href="qbitmap.html">QBitmap</a> +<li> <a href="qbrush.html">QBrush</a> +<li> <a href="qcursor.html">QCursor</a> +<li> <a href="qfont.html">QFont</a> +<li> <a href="qfontinfo.html">QFontInfo</a> +<li> <a href="qfontmetrics.html">QFontMetrics</a> +<li> <a href="qiconset.html">QIconSet</a> +<li> <a href="qmap.html">QMap</a> +<li> <a href="qpalette.html">QPalette</a> +<li> <a href="qpen.html">QPen</a> +<li> <a href="qpicture.html">QPicture</a> +<li> <a href="qpixmap.html">QPixmap</a> +<li> <a href="qregion.html">QRegion</a> +<li> <a href="qregexp.html">QRegExp</a> +<li> <a href="qstring.html">QString</a> +<li> <a href="qstringlist.html">QStringList</a> +<li> <a href="qvaluelist.html">QValueList</a> +<li> <a href="qvaluestack.html">QValueStack</a> +</ul> +<p> These classes automatically detach from common data if an object is +about to be changed. The programmer will not even notice that the +objects are shared. Thus you should treat separate instances of them +as separate objects. They will always behave as separate objects but +with the added benefit of sharing data whenever possible. For this +reason, you can pass instances of these classes as arguments to +functions by value without concern for the copying overhead. +<p> Example: +<pre> + <a href="qpixmap.html">QPixmap</a> p1, p2; + p1.<a href="qpixmap.html#load">load</a>( "image.bmp" ); + p2 = p1; // p1 and p2 share data + <a href="qpainter.html">QPainter</a> paint; + paint.<a href="qpainter.html#begin">begin</a>( &p2 ); // cuts p2 loose from p1 + paint.<a href="qpainter.html#drawText">drawText</a>( 0,50, "Hi" ); + paint.<a href="qpainter.html#end">end</a>(); +</pre> + +<p> In this example, <tt>p1</tt> and <tt>p2</tt> share data until <a href="qpainter.html#begin">QPainter::begin</a>() is +called for <tt>p2</tt>, because painting a pixmap will modify it. The same +also happens if anything is <a href="qimage.html#bitBlt">bitBlt()</a>'ed into +<tt>p2</tt>. +<p> <b>Warning:</b> Do not copy an implicitly shared container (<a href="qmap.html">QMap</a>, +<a href="qvaluevector.html">QValueVector</a>, etc.) while you are iterating over it. +<p> <h2> QCString: implicit or explicit? +</h2> +<a name="6"></a><p> <a href="qcstring.html">QCString</a> uses a mixture of implicit and explicit sharing. Functions +inherited from <a href="qbytearray.html">QByteArray</a>, such as data(), employ explicit sharing, while +those only in <a href="qcstring.html">QCString</a> detach automatically. Thus, QCString is rather an +"experts only" class, provided mainly to ease porting from Qt 1.x to Qt 2.0. +We recommend that you use <a href="qstring.html">QString</a>, a purely implicitly shared class. +<p> +<!-- eof --> +<p><address><hr><div align=center> +<table width=100% cellspacing=0 border=0><tr> +<td>Copyright © 2007 +<a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a> +<td align=right><div align=right>Qt 3.3.8</div> +</table></div></address></body> +</html> |