Improve implicit shared documentation a bit
Task-number: QTBUG-27061 Change-Id: I66e000a9f59fda3654066013e6e78c3ba6fd27fe Reviewed-by: Mitch Curtis <mitch.curtis@digia.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
cfb717d654
commit
499957eb8b
@ -273,3 +273,33 @@ QString onlyLetters(const QString &in)
|
||||
return out;
|
||||
}
|
||||
//! [23]
|
||||
|
||||
//! [24]
|
||||
QVector<int> a, b;
|
||||
a.resize(100000); // make a big vector filled with 0.
|
||||
|
||||
QVector<int>::iterator i = a.begin();
|
||||
// WRONG way of using the iterator i:
|
||||
b = a;
|
||||
/*
|
||||
Now we should be careful with iterator i since it will point to shared data
|
||||
If we do *i = 4 then we would change the shared instance (both vectors)
|
||||
The behavior differs from STL containers. Avoid doing such things in Qt.
|
||||
*/
|
||||
|
||||
a[0] = 5;
|
||||
/*
|
||||
Container a is now detached from the shared data,
|
||||
and even though i was an iterator from the container a, it now works as an iterator in b.
|
||||
Here the situation is that (*i) == 0.
|
||||
*/
|
||||
|
||||
b.clear(); // Now the iterator i is completely invalid.
|
||||
|
||||
int j = *i; // Undefined behavior!
|
||||
/*
|
||||
The data from b (which i pointed to) is gone.
|
||||
This would be well-defined with STL containers (and (*i) == 5),
|
||||
but with QVector this is likely to crash.
|
||||
*/
|
||||
//! [24]
|
||||
|
@ -533,10 +533,18 @@
|
||||
This problem doesn't occur with functions that return a const or
|
||||
non-const reference to a container.
|
||||
|
||||
\section3 Implicit sharing iterator problem
|
||||
|
||||
\l{Implicit sharing} has another consequence on STL-style
|
||||
iterators: You must not take a copy of a container while
|
||||
non-const iterators are active on that container. Java-style
|
||||
iterators don't suffer from that limitation.
|
||||
iterators: you should avoid copying a container while
|
||||
iterators are active on that container. The iterators
|
||||
point to an internal structure, and if you copy a container
|
||||
you should be very careful with your iterators. E.g:
|
||||
|
||||
\snippet code/doc_src_containers.cpp 24
|
||||
|
||||
The above example only shows a problem with QVector, but
|
||||
the problem exists for all the implicitly shared Qt containers.
|
||||
|
||||
\keyword foreach
|
||||
\section1 The foreach Keyword
|
||||
|
@ -89,9 +89,12 @@
|
||||
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
|
||||
Implicit sharing mostly takes place behind the scenes;
|
||||
the programmer rarely needs to worry about it. However, Qt's
|
||||
container iterators have different behavior than those from
|
||||
the STL. Read \l{Implicit sharing iterator problem}.
|
||||
|
||||
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}.
|
||||
|
||||
@ -105,9 +108,10 @@
|
||||
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
|
||||
An implicitly shared class has control of its internal data. In
|
||||
any member functions that modify its data, it automatically detaches
|
||||
before modifying the data.
|
||||
before modifying the data. Notice, however, the special case with
|
||||
container iterators; see \l{Implicit sharing iterator problem}.
|
||||
|
||||
The QPen class, which uses implicit sharing, detaches from the shared
|
||||
data in all member functions that change the internal data.
|
||||
@ -133,9 +137,9 @@
|
||||
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 iterators}{STL-style iterator}.
|
||||
\warning Be careful with copying an implicitly shared container
|
||||
(QMap, QVector, etc.) while you use
|
||||
\l{STL-style iterators}{STL-style iterator}. See \l{Implicit sharing iterator problem}.
|
||||
|
||||
\keyword implicitly shared classes
|
||||
\annotatedlist shared
|
||||
|
@ -1594,6 +1594,11 @@ void QHashData::checkSanity()
|
||||
need to keep iterators over a long period of time, we recommend
|
||||
that you use QMap rather than QHash.
|
||||
|
||||
\warning Iterators on implicitly shared containers do not work
|
||||
exactly like STL-iterators. You should avoid copying a container
|
||||
while iterators are active on that container. For more information,
|
||||
read \l{Implicit sharing iterator problem}.
|
||||
|
||||
\sa QHash::const_iterator, QMutableHashIterator
|
||||
*/
|
||||
|
||||
@ -1791,6 +1796,11 @@ void QHashData::checkSanity()
|
||||
internal data structure. If you need to keep iterators over a long
|
||||
period of time, we recommend that you use QMap rather than QHash.
|
||||
|
||||
\warning Iterators on implicitly shared containers do not work
|
||||
exactly like STL-iterators. You should avoid copying a container
|
||||
while iterators are active on that container. For more information,
|
||||
read \l{Implicit sharing iterator problem}.
|
||||
|
||||
\sa QHash::iterator, QHashIterator
|
||||
*/
|
||||
|
||||
|
@ -691,9 +691,12 @@ const QLinkedListData QLinkedListData::shared_null = {
|
||||
Multiple iterators can be used on the same list. If you add items
|
||||
to the list, existing iterators will remain valid. If you remove
|
||||
items from the list, iterators that point to the removed items
|
||||
will become dangling iterators. However, because of how \l{implicit
|
||||
sharing} works, you must not take a copy of a container while
|
||||
iterators are active on that container.
|
||||
will become dangling iterators.
|
||||
|
||||
\warning Iterators on implicitly shared containers do not work
|
||||
exactly like STL-iterators. You should avoid copying a container
|
||||
while iterators are active on that container. For more information,
|
||||
read \l{Implicit sharing iterator problem}.
|
||||
|
||||
\sa QLinkedList::const_iterator, QMutableLinkedListIterator
|
||||
*/
|
||||
@ -910,6 +913,11 @@ const QLinkedListData QLinkedListData::shared_null = {
|
||||
items from the list, iterators that point to the removed items
|
||||
will become dangling iterators.
|
||||
|
||||
\warning Iterators on implicitly shared containers do not work
|
||||
exactly like STL-iterators. You should avoid copying a container
|
||||
while iterators are active on that container. For more information,
|
||||
read \l{Implicit sharing iterator problem}.
|
||||
|
||||
\sa QLinkedList::iterator, QLinkedListIterator
|
||||
*/
|
||||
|
||||
|
@ -1292,6 +1292,11 @@ void **QListData::erase(void **xi)
|
||||
iterators over a long period of time, we recommend that you use
|
||||
QLinkedList rather than QList.
|
||||
|
||||
\warning Iterators on implicitly shared containers do not work
|
||||
exactly like STL-iterators. You should avoid copying a container
|
||||
while iterators are active on that container. For more information,
|
||||
read \l{Implicit sharing iterator problem}.
|
||||
|
||||
\sa QList::const_iterator, QMutableListIterator
|
||||
*/
|
||||
|
||||
@ -1542,6 +1547,11 @@ void **QListData::erase(void **xi)
|
||||
iterators over a long period of time, we recommend that you use
|
||||
QLinkedList rather than QList.
|
||||
|
||||
\warning Iterators on implicitly shared containers do not work
|
||||
exactly like STL-iterators. You should avoid copying a container
|
||||
while iterators are active on that container. For more information,
|
||||
read \l{Implicit sharing iterator problem}.
|
||||
|
||||
\sa QList::iterator, QListIterator
|
||||
*/
|
||||
|
||||
|
@ -1215,6 +1215,11 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
items from the map, iterators that point to the removed items
|
||||
will become dangling iterators.
|
||||
|
||||
\warning Iterators on implicitly shared containers do not work
|
||||
exactly like STL-iterators. You should avoid copying a container
|
||||
while iterators are active on that container. For more information,
|
||||
read \l{Implicit sharing iterator problem}.
|
||||
|
||||
\sa QMap::const_iterator, QMutableMapIterator
|
||||
*/
|
||||
|
||||
@ -1433,6 +1438,11 @@ void QMapDataBase::freeData(QMapDataBase *d)
|
||||
items from the map, iterators that point to the removed items
|
||||
will become dangling iterators.
|
||||
|
||||
\warning Iterators on implicitly shared containers do not work
|
||||
exactly like STL-iterators. You should avoid copying a container
|
||||
while iterators are active on that container. For more information,
|
||||
read \l{Implicit sharing iterator problem}.
|
||||
|
||||
\sa QMap::iterator, QMapIterator
|
||||
*/
|
||||
|
||||
|
@ -643,8 +643,12 @@
|
||||
|
||||
\snippet code/doc_src_qset.cpp 10
|
||||
|
||||
Multiple iterators can be used on the same set. However, you may
|
||||
not attempt to modify the container while iterating on it.
|
||||
Multiple iterators can be used on the same set.
|
||||
|
||||
\warning Iterators on implicitly shared containers do not work
|
||||
exactly like STL-iterators. You should avoid copying a container
|
||||
while iterators are active on that container. For more information,
|
||||
read \l{Implicit sharing iterator problem}.
|
||||
|
||||
\sa QSet::const_iterator, QMutableSetIterator
|
||||
*/
|
||||
@ -682,8 +686,10 @@
|
||||
|
||||
\snippet code/doc_src_qset.cpp 12
|
||||
|
||||
Multiple iterators can be used on the same set. However, you may
|
||||
not attempt to modify the container while iterating on it.
|
||||
\warning Iterators on implicitly shared containers do not work
|
||||
exactly like STL-iterators. You should avoid copying a container
|
||||
while iterators are active on that container. For more information,
|
||||
read \l{Implicit sharing iterator problem}.
|
||||
|
||||
\sa QSet::iterator, QSetIterator
|
||||
*/
|
||||
|
@ -957,6 +957,11 @@
|
||||
iterators}. The STL-style non-const iterator is simply a typedef
|
||||
for "T *" (pointer to T).
|
||||
|
||||
\warning Iterators on implicitly shared containers do not work
|
||||
exactly like STL-iterators. You should avoid copying a container
|
||||
while iterators are active on that container. For more information,
|
||||
read \l{Implicit sharing iterator problem}.
|
||||
|
||||
\sa QVector::begin(), QVector::end(), QVector::const_iterator, QMutableVectorIterator
|
||||
*/
|
||||
|
||||
@ -969,6 +974,11 @@
|
||||
iterators}. The STL-style const iterator is simply a typedef for
|
||||
"const T *" (pointer to const T).
|
||||
|
||||
\warning Iterators on implicitly shared containers do not work
|
||||
exactly like STL-iterators. You should avoid copying a container
|
||||
while iterators are active on that container. For more information,
|
||||
read \l{Implicit sharing iterator problem}.
|
||||
|
||||
\sa QVector::constBegin(), QVector::constEnd(), QVector::iterator, QVectorIterator
|
||||
*/
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user