Qt隐式数据共享 浅拷贝

  • Post author:
  • Post category:其他


原文链接:https://blog.csdn.net/cc321123123/article/details/41701611

QT5 中有一个Implicit Sharing的概念,叫做隐式共享,许多QT中许多C++类用隐式数据共享来减少copy带来的资源占用问题。

当作为参数传递时,隐式数据共享是安全和高效的,因为仅仅是指向数据的指针进行传递,而数据只在有函数对它进行改写是才进行复制。(copy on write)

QT的如下类均用到了这个机理,如果不希望进行隐式共享,则需要多加注意了。

QDBusPendingCall

The QDBusPendingCall class refers to one pending asynchronous call

QDBusUnixFileDescriptor

The QDBusUnixFileDescriptor class holds one Unix file descriptor.

QBitmap

The QBitmap class provides monochrome (1-bit depth) pixmaps.

QIcon

The QIcon class provides scalable icons in different modes and states.

QImage

The QImage class provides a hardware-independent image representation that allows direct access to the pixel data, and can be used as a paint device.

QPicture

The QPicture class is a paint device that records and replays QPainter commands.

QPixmap

The QPixmap class is an off-screen image representation that can be used as a paint device.

QCursor

The QCursor class provides a mouse cursor with an arbitrary shape.

QKeySequence

The QKeySequence class encapsulates a key sequence as used by shortcuts.

QPalette

The QPalette class contains color groups for each widget state.

QOpenGLDebugMessage

The QOpenGLDebugMessage class wraps an OpenGL debug message.

QBrush

The QBrush class defines the fill pattern of shapes drawn by QPainter.

QGradient

The QGradient class is used in combination with QBrush to specify gradient fills.

QPainterPath

The QPainterPath class provides a container for painting operations, enabling graphical shapes to be constructed and reused.

QPen

The QPen class defines how a QPainter should draw lines and outlines of shapes.

QPolygon

The QPolygon class provides a vector of points using integer precision.

QPolygonF

The QPolygonF class provides a vector of points using floating point precision.

QRegion

The QRegion class specifies a clip region for a painter.

QFont

The QFont class specifies a font used for drawing text.

QFontInfo

The QFontInfo class provides general information about fonts.

QFontMetrics

The QFontMetrics class provides font metrics information.

QFontMetricsF

The QFontMetricsF class provides font metrics information.

QGlyphRun

The QGlyphRun class provides direct access to the internal glyphs in a font.

QRawFont

The QRawFont class provides access to a single physical instance of a font.

QStaticText

The QStaticText class enables optimized drawing of text when the text and its layout is updated rarely.

QTextCursor

The QTextCursor class offers an API to access and modify QTextDocuments.

QTextDocumentFragment

The QTextDocumentFragment class represents a piece of formatted text from a QTextDocument.

QTextBlockFormat

The QTextBlockFormat class provides formatting information for blocks of text in a QTextDocument.

QTextCharFormat

The QTextCharFormat class provides formatting information for characters in a QTextDocument.

QTextFormat

The QTextFormat class provides formatting information for a QTextDocument.

QTextFrameFormat

The QTextFrameFormat class provides formatting information for frames in a QTextDocument.

QTextImageFormat

The QTextImageFormat class provides formatting information for images in a QTextDocument.

QTextListFormat

The QTextListFormat class provides formatting information for lists in a QTextDocument.

QTextTableCellFormat

The QTextTableCellFormat class provides formatting information for table cells in a QTextDocument.

QTextTableFormat

The QTextTableFormat class provides formatting information for tables in a QTextDocument.

QNetworkCacheMetaData

The QNetworkCacheMetaData class provides cache information.

QHttpPart

The QHttpPart class holds a body part to be used inside a HTTP multipart MIME message.

QNetworkCookie

The QNetworkCookie class holds one network cookie.

QNetworkRequest

The QNetworkRequest class holds a request to be sent with QNetworkAccessManager.

QNetworkConfiguration

The QNetworkConfiguration class provides an abstraction of one or more access point configurations.

QDnsDomainNameRecord

The QDnsDomainNameRecord class stores information about a domain name record.

QDnsHostAddressRecord

The QDnsHostAddressRecord class stores information about a host address record.

QDnsMailExchangeRecord

The QDnsMailExchangeRecord class stores information about a DNS MX record.

QDnsServiceRecord

The QDnsServiceRecord class stores information about a DNS SRV record.

QDnsTextRecord

The QDnsTextRecord class stores information about a DNS TXT record.

QNetworkAddressEntry

The QNetworkAddressEntry class stores one IP address supported by a network interface, along with its associated netmask and broadcast address.

QNetworkInterface

The QNetworkInterface class provides a listing of the host’s IP addresses and network interfaces.

QNetworkProxy

The QNetworkProxy class provides a network layer proxy.

QNetworkProxyQuery

The QNetworkProxyQuery class is used to query the proxy settings for a socket.

QSslCertificate

The QSslCertificate class provides a convenient API for an X509 certificate.

QSslCertificateExtension

The QSslCertificateExtension class provides an API for accessing the extensions of an X509 certificate.

QSslCipher

The QSslCipher class represents an SSL cryptographic cipher.

QSslConfiguration

The QSslConfiguration class holds the configuration and state of an SSL connection

QSslError

The QSslError class provides an SSL error.

QSslKey

The QSslKey class provides an interface for private and public keys.

QDebug

Output stream for debugging information

QDir

Access to directory structures and their contents

QFileInfo

System-independent file information

QProcessEnvironment

Holds the environment variables that can be passed to a program

QUrl

Convenient interface for working with URLs

QUrlQuery

Way to manipulate a key-value pairs in a URL’s query

QPersistentModelIndex

Used to locate data in a data model

QVariant

Acts like a union for the most common Qt data types

QMimeType

Describes types of file or data, represented by a MIME type string

QBitArray

Array of bits

QByteArray

Array of bytes

QCache

Template class that provides a cache

QCollator

Compares strings according to a localized collation algorithm

QCollatorSortKey

Can be used to speed up string collation

QCommandLineOption

Defines a possible command-line option

QContiguousCache

Template class that provides a contiguous cache

QDateTime

Date and time functions

QHash

Template class that provides a hash-table-based dictionary

QMultiHash

Convenience QHash subclass that provides multi-valued hashes

QLinkedList

Template class that provides linked lists

QList

Template class that provides lists

QLocale

Converts between numbers and their string representations in various languages

QMap

Template class that provides a red-black-tree-based dictionary

QMultiMap

Convenience QMap subclass that provides multi-valued maps

QQueue

Generic container that provides a queue

QRegExp

Pattern matching using regular expressions

QRegularExpression

Pattern matching using regular expressions

QRegularExpressionMatch

The results of a matching a QRegularExpression against a string

QRegularExpressionMatchIterator

Iterator on the results of a global match of a QRegularExpression object against a string

QSet

Template class that provides a hash-table-based set

QStack

Template class that provides a stack

QString

Unicode character string

QStringList

List of strings

QTextBoundaryFinder

Way of finding Unicode text boundaries in a string

QVector

Template class that provides a dynamic array

我昨天就一直被这个问题困扰着,因为

imageList.append(captureImage); //QList imageList; QImage captureImage; captureImage每隔一段时间刷新一次

imageList ,无论向imageList 中添加多少数据,imageList中的数据始终相同,并保持与最近一次captureImage中的数据一致。

后来我发现问题所在,QList中存放的应该是QImage对象的引用,每添加一次,只是添加了captureImage的引用,因此Qlist中的所有

元素都是指向captureImage的引用,因此都与最近一次captureImage中的数据一致。

要想调用imageList.append(captureImage); 时,每次的数据随着captureImage刷新,需要在调用之前,将captureImage的数据拷贝一份,

而简单的用QImage captureImg=captureImage;是实现不了拷贝的,因为这里QImage只做了浅拷贝,并不是我们想要的深拷贝。

为了实现我们的目的其实很简单只需在imageList.append(captureImage); 加上这个语句:captureImage.detach(); 然后再 QImage captureImg=captureImage;就可以了

具体请看:

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 copy-on-write or value semantics.)

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. Notice, however, the special case with container iterators; see 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.

Code fragment:

void QPen::setStyle(Qt::PenStyle style)

{


detach(); // detach from common data

d->style = style; // set the style member

}

void QPen::detach()

{


if (d->ref != 1) {


… // perform a deep copy

}

}