Spec-Zone.ru › Qt 5.15

Неявное совместное использование

Многие классы C++ в Qt используют неявное совместное использование данных, чтобы максимизировать использование ресурсов и свести к минимуму копирование. Неявно разделяемые классы безопасны и эффективны при передаче в качестве аргументов, поскольку передаётся только указатель на данные, а данные копируются только в том случае, если функция записывает в них, т. е. копирование при записи.

Обзор

Разделяемый класс состоит из указателя на общий блок данных, содержащий счётчик ссылок и данные.

При создании разделяемого объекта счётчик ссылок устанавливается в 1. Счётчик ссылок увеличивается всякий раз, когда новый объект ссылается на общие данные, и уменьшается, когда объект перестаёт ссылаться на общие данные. Общие данные удаляются, когда счётчик ссылок становится равным нулю.

При работе с разделяемыми объектами существует два способа копирования объекта. Обычно мы говорим о глубоком и поверхностном копировании. Глубокое копирование подразумевает дублирование объекта. Поверхностное копирование — это ссылка, т. е. просто указатель на общий блок данных. Глубокое копирование может быть дорогостоящим в плане памяти и процессорного времени. Поверхностное копирование очень быстрое, так как оно включает только установку указателя и увеличение счётчика ссылок.

Присваивание объектов (с оператором =()) для неявно разделяемых объектов реализуется с помощью поверхностного копирования.

Преимущество совместного использования заключается в том, что программе не нужно излишне дублировать данные, что приводит к меньшему использованию памяти и меньшему копированию данных. Объекты можно легко присваивать, отправлять в качестве аргументов функций и возвращать из функций.

Неявное совместное использование в основном происходит за кулисами; программисту редко нужно о нём беспокоиться. Однако итераторы контейнеров Qt ведут себя иначе, чем итераторы STL. Читайте проблему с итераторами при неявном совместном использовании.

В многопоточных приложениях неявное совместное использование происходит, как описано в разделе о потоках и неявно разделяемых классах.

При реализации собственных неявно разделяемых классов используйте классы 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
    }
}

Список классов

Нижеперечисленные классы автоматически отсоединяются от общих данных, если объект собирается изменить. Программист даже не заметит, что объекты разделяют данные. Поэтому следует рассматривать отдельные экземпляры этих классов как отдельные объекты. Они всегда будут вести себя как отдельные объекты, но с дополнительной возможностью совместного использования данных, когда это возможно. По этой причине вы можете передавать экземпляры этих классов в функции по значению без опасений относительно накладных расходов на копирование.

Пример:

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 и p2 делят данные до вызова QPainter::begin() для p2, поскольку рисование пиксельной карты приведет к её изменению.

Предупреждение: Будьте осторожны при копировании неявно разделяемого контейнера (QMap, QVector и т. д.) при использовании итераторов в стиле STL. См. проблему с итераторами при неявном совместном использовании.

QBitArray

Массив битов

QBitmap

Монохромные (глубина 1 бит) пикчеры

QBrush

Определяет образец заливки фигур, нарисованных QPainter

QByteArray

Массив байтов

QByteArrayList

Список массивов байтов

QCache

Шаблонный класс, предоставляющий кэш

QCollator

Сравнивает строки в соответствии с локальным алгоритмом сортировки

QCollatorSortKey

Может быть использован для ускорения сортировки строк

QCommandLineOption

Определяет возможный параметр командной строки

QContiguousCache

Шаблонный класс, предоставляющий непрерывный кэш

QCursor

Курсор мыши с произвольной формой

QDBusPendingCall

Относится к одному ожидающему асинхронному вызову

QDBusUnixFileDescriptor

Содержит один дескриптор Unix-файла

QDateTime

Функции даты и времени

QDebug

Поток вывода для отладочной информации

QDir

Доступ к структурам каталогов и их содержимому

QDnsDomainNameRecord

Хранит информацию о записи доменного имени

QDnsHostAddressRecord

Хранит информацию о записи адреса хоста

QDnsMailExchangeRecord

Хранит информацию о записи MX DNS

QDnsServiceRecord

Хранит информацию о записи SRV DNS

QDnsTextRecord

Хранит информацию о записи TXT DNS

QFileInfo

Независимая от платформы информация о файле

QFont

Указывает запрос для шрифта, используемого для отображения текста

QFontInfo

Общая информация о шрифтах

QFontMetrics

Информация о метриках шрифта

QFontMetricsF

Информация о метриках шрифта

QGlyphRun

Прямой доступ к внутренним глифам в шрифте

QGradient

Используется совместно с QBrush для указания градиентных заливок

QHash

Шаблонный класс, предоставляющий словарь на основе хеш-таблицы

QHostAddress

IP-адрес

QHttp2Configuration

Управляет параметрами и настройками HTTP/2

QHttpPart

Хранит часть тела для использования внутри сообщения HTTP multipart MIME

QIcon

Масштабируемые значки в различных режимах и состояниях

QImage

Независимая от аппаратной части представление изображения, позволяющее напрямую получить доступ к пиксельным данным и может быть использовано в качестве устройства рисования

QJsonArray

Инкапсулирует массив JSON

QJsonDocument

Способ чтения и записи документов JSON

QJsonObject

Инкапсулирует объект JSON

QJsonParseError

Используется для отчета об ошибках во время разбора JSON

QJsonValue

Инкапсулирует значение в JSON

QKeySequence

Инкапсулирует последовательность нажатий клавиш, как в сочетаниях клавиш

QList

Шаблонный класс, предоставляющий списки

QLocale

Преобразует числа в их строковые представления на различных языках

QMap

Шаблонный класс, предоставляющий словарь на основе красных-черных деревьев

QMimeType

Описывает типы файлов или данных, представленные строкой MIME-типа

QMultiHash

Удобный подкласс QHash, который предоставляет хеши с несколькими значениями

QMultiMap

Удобный подкласс QMap, который предоставляет карты с несколькими значениями

QNetworkAddressEntry

Хранит один IP-адрес, поддерживаемый сетевым интерфейсом, вместе с его ассоциированной маской сети и адресом широковещания

QNetworkCacheMetaData

Информация о кэше

QNetworkCookie

Хранит один сетевой cookie

QNetworkInterface

Список IP-адресов и сетевых интерфейсов хоста

QNetworkProxy

Прокси-сервер сетевого уровня

QNetworkProxyQuery

Используется для запроса параметров прокси для сокета

QNetworkRequest

Хранит запрос, который необходимо отправить с помощью QNetworkAccessManager

QOpenGLDebugMessage

Оборачивает сообщение об отладке OpenGL

QPainterPath

Контейнер для операций рисования, позволяющий строить и повторно использовать графические фигуры

QPalette

Содержит группы цветов для каждого состояния виджета

QPen

Определяет, как QPainter должен рисовать линии и контуры фигур

QPersistentModelIndex

Используется для поиска данных в модели данных

QPicture

Устройство рисования, которое записывает и воспроизводит команды QPainter

QPixmap

Представление изображения вне экрана, которое может использоваться в качестве устройства рисования

QPolygon

Вектор точек с целочисленной точностью

QPolygonF

Вектор точек с плавающей точкой

QProcessEnvironment

Содержит переменные среды, которые могут быть переданы программе

QQueue

Обобщенный контейнер, предоставляющий очередь

QRawFont

Доступ к одному физическому экземпляру шрифта

QRegExp

Сопоставление с образцом с помощью регулярных выражений

QRegion

Определяет область обрезки для художника

QRegularExpression

Сопоставление с образцом с помощью регулярных выражений

QRegularExpressionMatch

Результаты сопоставления QRegularExpression со строкой

QRegularExpressionMatchIterator

Итератор по результатам глобального сопоставления объекта QRegularExpression со строкой

QSet

Шаблонный класс, который предоставляет множество на основе хеш-таблицы

QSslCertificate

Удобный API для сертификата X509

QSslCertificateExtension

API для доступа к расширениям сертификата X509

QSslCipher

Представляет криптографический шифр SSL

QSslConfiguration

Содержит конфигурацию и состояние соединения SSL

QSslDiffieHellmanParameters

Интерфейс для параметров Diffie-Hellman для серверов

QSslError

Ошибка SSL

QSslKey

Интерфейс для закрытых и открытых ключей

QSslPreSharedKeyAuthenticator

Данные аутентификации для шифров с предварительно общими ключами (PSK)

QStack

Шаблонный класс, который предоставляет стек

QStaticText

Обеспечивает оптимизированный вывод текста, когда текст и его расположение обновляются редко

QStorageInfo

Предоставляет информацию о подключённых хранилищах и накопителях

QString

Строка Unicode

QStringList

Список строк

QTextBlockFormat

Информация о форматировании блоков текста в QTextDocument

QTextBoundaryFinder

Способ нахождения границ текста Unicode в строке

QTextCharFormat

Информация о форматировании символов в QTextDocument

QTextCursor

Предлагает API для доступа к QTextDocument и изменения его

QTextDocumentFragment

Представляет фрагмент форматированного текста из QTextDocument

QTextFormat

Информация о форматировании QTextDocument

QTextFrameFormat

Информация о форматировании фреймов в QTextDocument

QTextImageFormat

Информация о форматировании изображений в QTextDocument

QTextListFormat

Информация о форматировании списков в QTextDocument

QTextTableCellFormat

Информация о форматировании ячеек таблицы в QTextDocument

QTextTableFormat

Информация о форматировании таблиц в QTextDocument

QUrl

Удобный интерфейс для работы с URL-адресами

QUrlQuery

Способ манипулирования парами ключ-значение в запросе URL

QVariant

Выступает как объединение для наиболее распространённых типов данных Qt

QVector

Шаблонный класс, который предоставляет динамический массив

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.15/implicit-sharing.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API