隐式共享

Qt的许多类使用隐式数据共享, 最大限度提高资源使用率, 减少复制. 函数传参时, 隐式共享只传递数据指针, 既安全又高效, 并且只有函数往变量写入数据时, 数据才会复制, 即., 写时复制.

概述

共享类包含指向共享数据库的指针, 这个数据块包含引用计数和数据.

创建共享对象时, 引用计数设置为1. 有新对象引用共享数据时, 引用计数增加. 当对象取消引用共享数据时, 引用计数减少. 引用计数为0时, 删除共享数据.

处理共享对象时, 有两种方法复制对象. 我们通常讨论拷贝和拷贝. 深拷贝表示复制对象. 浅拷贝是一种引用复制, 即. 指向共享数据的指针. 对于内存和CPU而言, 深拷贝代价可能很高. 浅拷贝非常快, 因为它只涉及指针复制和引用计数.

隐式共享对象的对象分配采用浅拷贝.

隐式共享的好处是程序不需要进行不必要的数据复制, 这样可以降低内存的使用率, 减少数据复制. 对象容器分配, 作为函数参数传递, 作为函数返回值.

隐式共享发生在后台; 程序员不需要担心这个事情. 然而, Qt的容器迭代器与STL的不同. 阅读 Implicit sharing iterator problem.

在多线程应用程序中, 也会隐式共享, 参见 Threads and Implicitly Shared Classes.

使用 QSharedDataQSharedDataPointer 自定义隐式共享类.

隐式共享的细节

如果对象即将改变, 且引用计数大于1, 则隐式共享自动将对象与共享块分离. (这通常被称为 写时复制值语义.)

隐式共享类控制内部数据. 在任何修改数据的成员函数中, 它必须在修改数据之前自动分离数据. 注意: 隐式对象的容器迭代器必须考虑; 参见 Implicit sharing iterator problem.

QPen 使用隐式共享, 所有的成员函数在改变内部数据之前会分离共享数据.

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
      }
  }

类列表

下表列出的类在修改对象时, 自动分离公共数据. 开发人员甚至不会注意到这些对象是共享的. 因此, 你应该将它们的单独实例视为独立对象. 除非共享数据, 它们始终表现的跟独立对象一样. 因此, 你可以将这些类作为函数参数, 不必担心复制开销.

示例:


  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();

上述示例中, p1p2 在调用 QPainter::begin() 之前共享数据, 绘制修改图片.

警告: 使用STL风格迭代器时, 复制共享容器必须小心 (QMap, QVector等). 参见 Implicit sharing iterator problem.

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

QStorageInfo

Provides information about currently mounted storage and drives

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

QJsonArray

Encapsulates a JSON array

QJsonDocument

Way to read and write JSON documents

QJsonParseError

Used to report errors during JSON parsing

QJsonObject

Encapsulates a JSON object

QJsonValue

Encapsulates a value in JSON

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

QByteArrayList

List of byte arrays

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

QDBusPendingCall

Refers to one pending asynchronous call

QDBusUnixFileDescriptor

Holds one Unix file descriptor

QBitmap

Monochrome (1-bit depth) pixmaps

QIcon

Scalable icons in different modes and states

QImage

Hardware-independent image representation that allows direct access to the pixel data, and can be used as a paint device

QPicture

Paint device that records and replays QPainter commands

QPixmap

Off-screen image representation that can be used as a paint device

QCursor

Mouse cursor with an arbitrary shape

QKeySequence

Encapsulates a key sequence as used by shortcuts

QPalette

Contains color groups for each widget state

QOpenGLDebugMessage

Wraps an OpenGL debug message

QBrush

Defines the fill pattern of shapes drawn by QPainter

QGradient

Used in combination with QBrush to specify gradient fills

QPainterPath

Container for painting operations, enabling graphical shapes to be constructed and reused

QPen

Defines how a QPainter should draw lines and outlines of shapes

QPolygon

Vector of points using integer precision

QPolygonF

Vector of points using floating point precision

QRegion

Specifies a clip region for a painter

QFont

Specifies a font used for drawing text

QFontInfo

General information about fonts

QFontMetrics

Font metrics information

QFontMetricsF

Font metrics information

QGlyphRun

Direct access to the internal glyphs in a font

QRawFont

Access to a single physical instance of a font

QStaticText

Enables optimized drawing of text when the text and its layout is updated rarely

QTextCursor

Offers an API to access and modify QTextDocuments

QTextDocumentFragment

Represents a piece of formatted text from a QTextDocument

QTextBlockFormat

Formatting information for blocks of text in a QTextDocument

QTextCharFormat

Formatting information for characters in a QTextDocument

QTextFormat

Formatting information for a QTextDocument

QTextFrameFormat

Formatting information for frames in a QTextDocument

QTextImageFormat

Formatting information for images in a QTextDocument

QTextListFormat

Formatting information for lists in a QTextDocument

QTextTableCellFormat

Formatting information for table cells in a QTextDocument

QTextTableFormat

Formatting information for tables in a QTextDocument

QNetworkCacheMetaData

Cache information

QHttpPart

Holds a body part to be used inside a HTTP multipart MIME message

QNetworkCookie

Holds one network cookie

QNetworkRequest

Holds a request to be sent with QNetworkAccessManager

QNetworkConfiguration

Abstraction of one or more access point configurations

QDnsDomainNameRecord

Stores information about a domain name record

QDnsHostAddressRecord

Stores information about a host address record

QDnsMailExchangeRecord

Stores information about a DNS MX record

QDnsServiceRecord

Stores information about a DNS SRV record

QDnsTextRecord

Stores information about a DNS TXT record

QHostAddress

IP address

QNetworkAddressEntry

Stores one IP address supported by a network interface, along with its associated netmask and broadcast address

QNetworkInterface

Listing of the host's IP addresses and network interfaces

QNetworkProxy

Network layer proxy

QNetworkProxyQuery

Used to query the proxy settings for a socket

QSslCertificate

Convenient API for an X509 certificate

QSslCertificateExtension

API for accessing the extensions of an X509 certificate

QSslCipher

Represents an SSL cryptographic cipher

QSslConfiguration

Holds the configuration and state of an SSL connection

QSslDiffieHellmanParameters

Interface for Diffie-Hellman parameters for servers

QSslError

SSL error

QSslKey

Interface for private and public keys

QSslPreSharedKeyAuthenticator

Authentication data for pre shared keys (PSK) ciphersuites