Неявное разделение данных
Many C++ classes in Qt use implicit data sharing to maximize resource usage and minimize copying. Implicitly shared classes are both safe and efficient when passed as arguments, because only a pointer to the data is passed around, and the data is copied only if and when a function writes to it, i.e., copy-on-write.
Краткий обзор
A shared class consists of a pointer to a shared data block that contains a reference count and the data.
When a shared object is created, it sets the reference count to 1. The reference count is incremented whenever a new object references the shared data, and decremented when the object dereferences the shared data. The shared data is deleted when the reference count becomes zero.
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 Threads and Implicitly Shared Classes.
When implementing your own implicitly shared classes, use the QSharedData and QSharedDataPointer classes.
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 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.
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
}
}
Список классов
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();
In this example, p1 and p2 share data until QPainter::begin() is called for 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 STL-style iterator.
QBitArray | Битовый массив |
QBitmap | Монохромное (глубина в 1 бит) растровое изображение |
QBrush | Определяет образец заливки фигур, отображаемых с помощью QPainter |
QByteArray | Байтовый массив |
QCache | Класс-шаблон, реализующий кэш |
QContiguousCache | Класс-шаблон, предоставляющий непрерывный кэш |
QCursor | Указатель мыши произвольной формы |
QDir | Доступ к структуре каталогов и их содержимому |
QFileInfo | Независимая от системы информация о файле |
QFont | Устанавливает шрифт, используемый для отрисовки текста |
QFontInfo | Общая информация о шрифтах |
QFontMetrics | Информация о метриках шрифта |
QFontMetricsF | Информация о метриках шрифта |
QGLColormap | Используется для установки пользовательской карты цветов в QGLWidget |
QGradient | Используется совместно с QBrush для задания градиентной заливки |
QHash | Класс-шаблон для представления словаря, основанного на хэш-таблице |
QIcon | Масштабируемые пиктограммы для различных режимов и состояний |
QImage | Аппаратно-независимое представление изображения, предоставляющее прямой доступ к пикселям и способная работать в качестве устройства рисования |
QKeySequence | Содержит последовательность клавиш, используемую как горячие клавиши |
QLinkedList | Класс-шаблон, реализующий связанный список |
QList | Класс-шаблон, реализующий связанный список |
QLocale | Конвертирует числа в их строковые представления на различных языках |
QMap | Класс-шаблон, реализующий список, основанный на словаре |
QMultiHash | Вспомогательный подкласс QHash, предоставляющий хэширование нескольких значений |
QMultiMap | Вспомогательный подкласс QMap, предоставляющий карты с несколькими значениями |
QPainterPath | Контейнер для операций рисования, позволяющий создавать и повторно использовать графические фигуры |
QPalette | Содержит цветовые группы для каждого состояния виджета |
QPen | Задает для QPainter способ рисования линий и контуров фигур |
QPicture | Устройство рисования, запоминающее и повторяющее команды QPainter |
QPixmap | Неэкранное представление изображения, которое может использоваться в качестве устройства рисования |
QPolygon | Вектор точек с координатами, заданными целыми числами |
QPolygonF | Вектор точек с координатами, заданными числами с плавающей точкой |
QQueue | Общий контейнер, реализующий очередь |
QRegExp | Проверка соответствия используемому регулярному выражению |
QRegion | Устанавливает область отсечения для рисовальщика (painter) |
QSet | Класс-шаблон набора, основанного на хэшированной таблице |
QSqlField | Управление полями в таблицах и представлениях базы данных SQL |
QSqlQuery | Средства управления выражениями SQL и их выполнения |
QSqlRecord | Заключает в себе запись базы данных |
QStack | Класс-шаблон стека |
QString | Строка символов Unicode |
QStringList | Список строк |
QTextBoundaryFinder | Способ поиска границ текста Unicode в строке |
QTextCursor | Предлагает API для доступа к объектам QTextDocument и изменению их содержимого |
QTextDocumentFragment | Представляет фрагмент форматированного текста из QTextDocument |
QTextFormat | Информация о форматировании в QTextDocument |
QUrl | Вспомогательный интерфейс для работы с адресами URL |
QVariant | Действует аналогично объединению для большинства общих типов данных Qt |
QVector | Класс-шаблон, представляющий динамический массив |
QX11Info | Информация о конфигурации X-дисплея |
Авторские права © 2010 Nokia Corporation и/или её дочерние компании |
Торговые марки |
Qt 4.6.4 |
|