From d796c9dd933ab96ec83b9a634feedd5d32e1ba3f Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Tue, 8 Nov 2011 12:31:36 -0600 Subject: Test conversion to TQt3 from Qt3 8c6fc1f8e35fd264dd01c582ca5e7549b32ab731 --- doc/html/shclass.html | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 doc/html/shclass.html (limited to 'doc/html/shclass.html') diff --git a/doc/html/shclass.html b/doc/html/shclass.html new file mode 100644 index 000000000..416c211a6 --- /dev/null +++ b/doc/html/shclass.html @@ -0,0 +1,236 @@ + + + + + +Shared Classes + + + + + + + +
+ +Home + | +All Classes + | +Main Classes + | +Annotated + | +Grouped Classes + | +Functions +

Shared Classes

+ + + +

+

Many C++ classes in TQt use explicit and implicit data sharing +to maximize resource usage and minimize copying of data. +

+

+ + +

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. +

+

When dealing with shared objects, there are two ways of copying an +object. We usually speak about deep and 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 TQDeepCopy. +

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 explicit and 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. +

A TQByteArray Example +

+

TQByteArray is an example of a shared class that uses explicit sharing. +Example: +

+                          //Line    a=         b=         c=
+    TQByteArray 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}
+    TQByteArray 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}
+
+ +

The assignment a = b on line 3 throws away a's original shared +block (the reference count becomes zero), sets a's shared block to +point to b's shared block and increments the reference count. +

On line 4, the contents of a is modified. b is also modified, +because a and b refer to the same data block. This is the +difference between explicit and implicit sharing (explained below). +

The 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 a on line 7 does not +affect b or c. +

Finally, on line 8 we make a deep copy of a and assign it to b, +so that when a is modified on line 9, b remains unchanged. +

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 TQByteArray, cannot +be implicitly shared, because it can be changed without letting +TQByteArray 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 TQPen class, which uses implicit sharing, detaches from the shared +data in all member functions that change the internal data. +

Code fragment: +

+    void TQPen::setStyle( PenStyle s )
+    {
+        detach();        // detach from common data
+        data->style = s; // set the style member
+    }
+
+    void TQPen::detach()
+    {
+        if ( data->count != 1 ) // only if >1 reference
+            *this = copy();
+    }
+
+ +

This is clearly not possible for TQByteArray, because the programmer +can do the following: +

+    TQByteArray array( 10 );
+    array.fill( 'a' );
+    array[0] = 'f';        // will modify array
+    array.data()[1] = 'i'; // will modify array
+
+ +

If we monitor changes in a TQByteArray, the TQByteArray class would +become unacceptably slow. +

Explicitly Shared Classes +

+

All classes that are instances of the TQMemArray template class are +explicitly shared: +

+

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 TQImage, which does not inherit TQMemArray. TQMovie is also explicitly shared, but it does not support detach() or +copy(). +

Implicitly Shared Classes +

+

The TQt classes that are implicitly shared are: +

+

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: +

+    TQPixmap p1, p2;
+    p1.load( "image.bmp" );
+    p2 = p1;                    // p1 and p2 share data
+    TQPainter paint;
+    paint.begin( &p2 );         // cuts p2 loose from p1
+    paint.drawText( 0,50, "Hi" );
+    paint.end();
+
+ +

In this example, p1 and p2 share data until TQPainter::begin() is +called for p2, because painting a pixmap will modify it. The same +also happens if anything is bitBlt()'ed into +p2. +

Warning: Do not copy an implicitly shared container (TQMap, +TQValueVector, etc.) while you are iterating over it. +

TQCString: implicit or explicit? +

+

TQCString uses a mixture of implicit and explicit sharing. Functions +inherited from TQByteArray, such as data(), employ explicit sharing, while +those only in TQCString detach automatically. Thus, TQCString is rather an +"experts only" class, provided mainly to ease porting from TQt 1.x to TQt 2.0. +We recommend that you use TQString, a purely implicitly shared class. +

+ +


+ +
Copyright © 2007 +TrolltechTrademarks +
TQt 3.3.8
+
+ -- cgit v1.2.1