隱式共享

Qt 中的很多 C++ 類使用隱式數據共享,以最大化利用資源並最小化拷貝。隱式共享類既安全又高效當作為參數傳遞時,因為僅傳遞指嚮數據的指針,且僅當函數寫入時纔拷貝數據,即 寫入時拷貝 .

概述

共享類由指嚮包含引用計數和引用數據的共享數據塊的指針組成。

當創建共享對象時,它將引用計數設為 1。遞增引用計數,每當新對象引用共享數據時。和遞減引用計數,當對象解引用共享數據時。刪除共享數據,當引用計數變為 0 時。

When dealing with shared objects, there are two ways of copying an object. We usually speak about deep and 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 綫程和隱式共享類 .

當實現自己的隱式共享類時,使用 QSharedData and QSharedDataPointer 類。

隱式共享細節

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 寫入時拷貝 or 值語義 )。

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.

代碼片段:

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

類列錶

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.

範例:

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

在此範例中, p1 and p2 共享數據直到 QPainter::begin () 被調用對於 p2 ,因為描繪像素圖會修改它。

警告: Do not copy an implicitly shared container ( QMap , QVector , etc.) while you are iterating over it using an non-const STL-style iterator.

OpenGL QGLColormap class is used for installing custom colormaps into a QGLWidget
QBitArray 位數組
QBitmap 單色 (1 位深度) 像素圖
QBrush 定義 QPainter 繪製形狀的填充圖案
QByteArray 字節數組
QCache 提供緩存的模闆類
QContiguousCache 提供連續緩存的模闆類
QCursor 具有任意形狀的鼠標光標
QDir 訪問目錄結構及其內容
QFileInfo 與係統無關的文件信息
QFont Specifies a font used for drawing text
QFontInfo 有關字體的一般信息
QFontMetrics 字體規格信息
QFontMetricsF 字體規格信息
QGradient 用於組閤 QBrush 以指定漸變填充
QHash 提供基於哈希錶的字典的模闆類
QIcon 在不同模式和狀態下的可伸縮圖標
QImage 獨立於硬件的圖像錶示 (允許直接訪問像素數據,且可以被用作描繪設備)
QKeySequence 封裝作為快捷鍵使用的鍵序列
QLinkedList 提供鏈接列錶的模闆類
QList 提供列錶的模闆類
QLocale 在數字及其各種語言的字符串錶示之間轉換
QMap Template class that provides a skip-list-based dictionary
QMultiHash 提供多值哈希的方便 QHash 子類
QMultiMap 提供多值映射的方便 QMap 子類
QPainterPath 用於描繪操作的容器,使圖形形狀能夠被構造和重用
QPalette 包含各 Widget 狀態的顔色組
QPen 定義 QPainter 如何繪製綫條和形狀的輪廓
QPicture 用於記錄和重演 QPainter 命令的描繪設備
QPixmap 可以用作描繪設備的離屏圖像錶示
QPolygon 使用整數精度的點嚮量
QPolygonF 使用浮點精度的點嚮量
QQueue 提供隊列的通用容器
QRegExp 使用正則錶達式進行模式匹配
QRegion 為描繪器指定裁剪區域
QSet 提供基於哈希錶的集的模闆類
QSqlField 操縱 SQL 數據庫錶和視圖中的字段
QSqlQuery 執行和操縱 SQL 語句的手段
QSqlRecord 封裝數據庫記錄
QStack 提供堆棧的模闆類
QString Unicode 字符串
QStringList 字符串列錶
QTextBoundaryFinder 在字符串中查找 Unicode 文本邊界的辦法
QTextCursor 提供訪問和修改 QTextDocument 的 API
QTextDocumentFragment 錶示一塊來自 QTextDocument 的格式化文本
QTextFormat 用於 QTextDocument 的格式化信息
QUrl 用於操控 URL 的方便接口
QVariant 舉動像最常見 Qt 數據類型的並集
QVector 提供動態數組的模闆類
QX11Info Information about the X display configuration