1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms
** and conditions contained in a signed written agreement between you
** and Nokia.
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/* TODO: Move some of the documentation from QSharedDataPointer into this
document. */
/*!
\group shared
\title Implicitly Shared Classes
*/
/*!
\page implicit-sharing.html
\title Implicit Sharing
\ingroup qt-basic-concepts
\brief Reference counting for fast copying.
\keyword implicit data sharing
\keyword implicit sharing
\keyword implicitly shared
\keyword reference counting
\keyword shared implicitly
\keyword shared classes
Many C++ classes in Qt use implicit data sharing to maximize
resource usage and minimize copying. Implicitly shared classes are
both safe and efficient when passed as arguments, because only a
pointer to the data is passed around, and the data is copied only
if and when a function writes to it, i.e., \e {copy-on-write}.
\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 shared objects is
implemented using shallow copies.
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.
Implicit sharing takes place behind the scenes; the programmer
does not need to worry about it. Even in multithreaded
applications, implicit sharing takes place, as explained in
\l{Thread-Support in Qt Modules#Threads and Implicitly Shared Classes}
{Threads and Implicitly Shared Classes}.
When implementing your own implicitly shared classes, use the
QSharedData and QSharedDataPointer classes.
\section1 Implicit Sharing in Detail
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 \e {copy-on-write} or
\e {value semantics}.)
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:
\snippet doc/src/snippets/code/doc_src_groups.cpp 0
\section1 List of Classes
The classes listed below 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:
\snippet doc/src/snippets/code/doc_src_groups.cpp 1
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.
\warning Do not copy an implicitly shared container (QMap,
QVector, etc.) while you are iterating over it using an non-const
\l{STL-style iterator}.
\keyword implicitly shared classes
\annotatedlist shared
*/
|