Qt文档阅读笔记-隐式共享(Implicit Sharing)深入研究(理论及实例)

Qt里面很多C++类都是采用隐式共享最大限度的提高资源利用率以及最新复制的原则。隐式共享数据作为参数时,不仅安全而且高效,因为传的是一个指针并且只有要修改这个数据时才会去拷贝,这里有个专业词汇copy-on-write在Qt官方提供的ppt中经常会出现这个词,说的就是隐式共享。

 

共享类(这个应该是指value type的类,学过Qt的都知道,Qt类可以分为两类,一个是identity type和value type)由一个共享数据块及指向这个块的计数器组成。

当共享对象被创建,这个块的计数器的值会被设置为1,并且当有新的对象指向共享数据库,那么他的计数器就会+1,当对象不指向这个内存块时,计数器会减少,当计数器为0时,这个共享块将会被删除。

当要对共享数据进行处理时,Qt有2种方式进行拷贝,也就是常说的深拷贝与浅拷贝。这里不再解释这2个拷贝了,这个隐式共享就和浅拷贝差不多,只不过是多了给增加了个引用计数器。

=这个操作一般是浅拷贝。

 

Qt的容器iterator和STL的不同,主要也是围绕隐式共享。如下代码:

#include <QVector>
#include <QDebug>

int main(int argc, char *argv[])
{
    QVector<int> a, b;
    a.resize(100000);

    QVector<int>::iterator i = a.begin();
    b = a;

    *i = 4;
    a[0] = 5;

    b.clear();

    int j = *i;


    qDebug() << "OVER";

}

下面最关键的来了,演示下上面所说的理论

这里可以看到当*i = 4还没执行的时候a中RefCount为2,也就是a,b都引用到了这个隐式内存中,所以为2。而这个i是直接指向了目前a最开始的那个内存。

下面看下一张图:

这里可以看到*i=4改变后,因为改变的是共享内存,所有a和b里面的数据都被改了。

最关键的地方来了,大家要注意,Qt最强大的机制之一copy-on-write来了。

这里a[0]=5,写及拷贝。a重新进行构造,现在RefCount又变成1了。

这个程序想表示的就是这个。也就是Qt很重要的运行机制。

还有给要提的就是这个i。

当b被clear后这个i就有问题,int j = i;这种操作很不安全。

 

当开发者需要写自己的隐式共享类时,使用QSharedData和QSharedDataPointer类。

 

当需要改变数据的时候,数据将会从隐式共享分离。

如下面这个QPen类,内部是这样处理的

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

当setStyle被调用后,这个set为设置,所以改变了,就会调用detach(),当d-ref不为1时,就会把所有数据拷贝一份。

 

下面是一些隐式共享的类,这里要记住,QTL的容器如果用STL风格去操作,需要考虑下隐式共享方面的问题。

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

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

©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页