summaryrefslogtreecommitdiffstats
path: root/doc/shclass.doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc/shclass.doc')
-rw-r--r--doc/shclass.doc260
1 files changed, 260 insertions, 0 deletions
diff --git a/doc/shclass.doc b/doc/shclass.doc
new file mode 100644
index 0000000..418dd45
--- /dev/null
+++ b/doc/shclass.doc
@@ -0,0 +1,260 @@
+/****************************************************************************
+**
+** Qt Shared Classes Documentation
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the Qt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.QPL
+** included in the packaging of this file. Licensees holding valid Qt
+** Commercial licenses may use this file in accordance with the Qt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/*!
+\page shclass.html
+
+\title Shared Classes
+
+\keyword reference counting
+\keyword implicit sharing
+\keyword explicit sharing
+\keyword implicitly shared
+\keyword explicitly shared
+\keyword explicit sharing
+\keyword shared implicitly
+\keyword shared explicitly
+
+Many C++ classes in Qt use \e explicit and \e implicit data sharing
+to maximize resource usage and minimize copying of data.
+
+\tableofcontents
+
+\section1 Overview
+
+A shared class consists of a pointer to a shared data block that
+contains a reference count and the data.
+
+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.
+
+\keyword deep copy
+\keyword shallow copy
+
+When dealing with shared objects, there are two ways of copying an
+object. We usually speak about \e deep and \e shallow 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.
+
+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 \l QDeepCopy.
+
+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.
+
+Now comes the distinction between \e explicit and \e implicit 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.
+
+\section1 A QByteArray Example
+
+QByteArray is an example of a shared class that uses explicit sharing.
+Example:
+\code
+ //Line a= b= c=
+ QByteArray 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}
+ QByteArray c = a; // 5: {12,56} {12,56} {12,56}
+ a.detach(); // 6: {12,56} {12,56} {12,56}
+ a[1] = 78; // 7: {12,78} {12,56} {12,56}
+ b = a.copy(); // 8: {12,78} {12,78} {12,56}
+ a[1] = 90; // 9: {12,90} {12,78} {12,56}
+\endcode
+
+The assignment \c {a = b} on line 3 throws away \c a's original shared
+block (the reference count becomes zero), sets \c a's shared block to
+point to \c b's shared block and increments the reference count.
+
+On line 4, the contents of \c a is modified. \c b is also modified,
+because \c a and \c b refer to the same data block. This is the
+difference between explicit and implicit sharing (explained below).
+
+The \c a 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 \c a on line 7 does not
+affect \c b or \c c.
+
+Finally, on line 8 we make a deep copy of \c a and assign it to \c b,
+so that when \c a is modified on line 9, \c b remains unchanged.
+
+
+\section1 Explicit vs. Implicit Sharing
+
+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.
+
+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 QByteArray, cannot
+be implicitly shared, because it can be changed without letting
+QByteArray know.
+
+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.
+
+The QPen class, which uses implicit sharing, detaches from the shared
+data in all member functions that change the internal data.
+
+Code fragment:
+\code
+ 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();
+ }
+\endcode
+
+This is clearly not possible for QByteArray, because the programmer
+can do the following:
+
+\code
+ QByteArray array( 10 );
+ array.fill( 'a' );
+ array[0] = 'f'; // will modify array
+ array.data()[1] = 'i'; // will modify array
+\endcode
+
+If we monitor changes in a QByteArray, the QByteArray class would
+become unacceptably slow.
+
+
+\section1 Explicitly Shared Classes
+
+All classes that are instances of the QMemArray template class are
+explicitly shared:
+
+\list
+\i \l QBitArray
+\i \l QPointArray
+\i \l QByteArray
+\i Any other instantiation of \link QMemArray QMemArray\<type\>\endlink
+\endlist
+
+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.
+
+The same is true for \l QImage, which does not inherit QMemArray. \l
+QMovie is also explicitly shared, but it does not support detach() or
+copy().
+
+\section1 Implicitly Shared Classes
+
+The Qt classes that are implicitly shared are:
+\list
+\i \l QBitmap
+\i \l QBrush
+\i \l QCursor
+\i \l QFont
+\i \l QFontInfo
+\i \l QFontMetrics
+\i \l QIconSet
+\i \l QMap
+\i \l QPalette
+\i \l QPen
+\i \l QPicture
+\i \l QPixmap
+\i \l QRegion
+\i \l QRegExp
+\i \l QString
+\i \l QStringList
+\i \l QValueList
+\i \l QValueStack
+\endlist
+
+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.
+
+Example:
+\code
+ QPixmap p1, p2;
+ p1.load( "image.bmp" );
+ p2 = p1; // p1 and p2 share data
+ QPainter paint;
+ paint.begin( &p2 ); // cuts p2 loose from p1
+ paint.drawText( 0,50, "Hi" );
+ paint.end();
+\endcode
+
+In this example, \c p1 and \c p2 share data until QPainter::begin() is
+called for \c p2, because painting a pixmap will modify it. The same
+also happens if anything is \link ::bitBlt() bitBlt()\endlink'ed into
+\c p2.
+
+\warning Do not copy an implicitly shared container (QMap,
+QValueVector, etc.) while you are iterating over it.
+
+\section1 QCString: implicit or explicit?
+
+\l QCString uses a mixture of implicit and explicit sharing. Functions
+inherited from QByteArray, such as data(), employ explicit sharing, while
+those only in QCString 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 \l QString, a purely implicitly shared class.
+
+*/