Неявное совместное использование
Многие классы 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 совместно используют данные до тех пор, пока для p2 не будет вызван QPainter::begin(), так как рисование пиксельной карты изменит её.
Предупреждение: Будьте осторожны при копировании контейнера с неявным совместным использованием (QMap, QList и т. д.) во время использования итераторов STL-стиля. См. Проблему итераторов с неявным совместным использованием.
Массив битов |
|
Монохромные (глубина 1 бит) растровые изображения |
|
Определяет узор заливки фигур, нарисованных с помощью QPainter |
|
Массив байтов |
|
Список массивов байтов |
|
Вид на массив байтов с только для чтения подмножеством API QByteArray |
|
Шаблонный класс, предоставляющий кэш |
|
Сравнивает строки в соответствии с алгоритмом сортировки, локализованным для данной языковой среды |
|
Может использоваться для ускорения сортировки строк |
|
Определяет возможный параметр командной строки |
|
Шаблонный класс, предоставляющий непрерывный кэш |
|
Курсор мыши с произвольной формой |
|
Относится к одному ожидающему асинхронному вызову |
|
Содержит один дескриптор Unix-файла |
|
Функции даты и времени |
|
Поток вывода для отладочной информации |
|
Доступ к структурам каталогов и их содержимому |
|
Хранит информацию о записи доменного имени |
|
Хранит информацию о записи адреса хоста |
|
Хранит информацию о записи MX DNS |
|
Хранит информацию о записи SRV DNS |
|
Хранит информацию о записи TXT DNS |
|
Независимая от платформы информация о файле |
|
Указывает параметры шрифта для вывода текста |
|
Общая информация о шрифтах |
|
Информация о метриках шрифта |
|
Информация о метриках шрифта |
|
Описывает параметры области или региона, которые необходимо отслеживать на предмет близости |
|
Содержит информацию, собранную о глобальном положении, направлении и скорости в определенный момент времени |
|
Содержит основную информацию о спутнике |
|
Прямой доступ к внутренним глифам шрифта |
|
Используется в сочетании с QBrush для задания градиентной заливки |
|
Шаблонный класс, предоставляющий словарь на основе хеш-таблицы |
|
IP-адрес |
|
Управляет параметрами и настройками HTTP/2 |
|
Содержит часть тела, используемую внутри сообщения HTTP multipart MIME |
|
Масштабируемые значки в различных режимах и состояниях |
|
Независимая от аппаратного обеспечения структура изображения, позволяющая получить прямой доступ к данным пикселей и может быть использована в качестве устройства отрисовки |
|
Запрещает массив JSON |
|
Способ чтения и записи документов JSON |
|
Запрещает объект JSON |
|
Используется для сообщения об ошибках при разборе JSON |
|
Запрещает значение в JSON |
|
Запрещает последовательность нажатий клавиш, используемую в сочетаниях клавиш |
|
Шаблонный класс, предоставляющий связанные списки |
|
Шаблонный класс, предоставляющий динамический массив |
|
Преобразует числа в строки и обратно в различных языках |
|
Представляет данные, которые необходимо транслировать во время рекламы Bluetooth Low Energy |
|
Представляет параметры, используемые для рекламы Bluetooth Low Energy |
|
Используется для настройки данных сервиса GATT |
|
Используется при запросе или сообщении об обновлении параметров подключения Bluetooth LE |
|
Используется для создания данных сервиса GATT |
|
Используется для настройки данных сервиса GATT |
|
Шаблонный класс, предоставляющий ассоциативный массив |
|
Определяет типы файлов или данных, представленные строкой MIME-типа |
|
Представляет фильтр тем MQTT |
|
Представляет имя темы MQTT |
|
Подкласс QHash, предоставляющий хеши с множественными значениями |
|
Шаблонный класс, предоставляющий ассоциативный массив с несколькими эквивалентными ключами |
|
Хранит один IP-адрес, поддерживаемый сетевым интерфейсом, вместе с его маской сети и широковещательным адресом |
|
Информация о кэше |
|
Содержит один сетевой cookie |
|
Список IP-адресов и сетевых интерфейсов хоста |
Прокси-сервер сетевого уровня |
|
Используется для запроса настроек прокси-сервера для сокета |
|
Содержит запрос, который должен быть отправлен с помощью QNetworkAccessManager |
|
Оборачивает сообщение об отладке OpenGL |
|
Представляет собой набор диапазонов страниц |
|
Контейнер для операций рисования, позволяющий строить и повторно использовать графические фигуры |
|
Содержит группы цветов для каждого состояния виджета |
|
Определяет, как QPainter должен рисовать линии и контуры фигур |
|
Используется для поиска данных в модели данных |
|
Устройство рисования, которое записывает и воспроизводит команды QPainter |
|
Представление изображения вне экрана, которое может использоваться в качестве устройства рисования |
|
Список точек с использованием целочисленной точности |
|
Список точек с использованием плавающей точки |
|
Содержит переменные среды, которые могут быть переданы программе |
|
Общий контейнер, который предоставляет очередь |
|
Доступ к одному физическому экземпляру шрифта |
|
Сопоставление с образцом с использованием регулярных выражений |
|
Определяет область обрезки для художника |
|
Сопоставление с образцом с использованием регулярных выражений |
|
Результаты сопоставления QRegularExpression со строкой |
|
Итератор по результатам глобального сопоставления объекта QRegularExpression со строкой |
|
Шаблонный класс, который предоставляет набор на основе хэш-таблицы |
|
Обрабатывает поля в таблицах и представлениях баз данных SQL |
|
Способ выполнения и обработки SQL-запросов |
|
Оборачивает запись базы данных |
|
Удобный API для сертификата X509 |
|
API для доступа к расширениям сертификата X509 |
|
Представляет собой криптографический шифр SSL |
|
Содержит конфигурацию и состояние подключения SSL |
|
Интерфейс для параметров Diffie-Hellman для серверов |
|
Ошибка SSL |
|
Интерфейс для закрытых и открытых ключей |
|
Данные аутентификации для шифров с предварительно объявленными ключами (PSK) |
|
Шаблонный класс, который предоставляет стек |
|
Обеспечивает оптимизированное отображение текста, когда текст и его макет обновляются редко |
|
Предоставляет информацию о смонтированных хранилищах и дисках |
|
Строка символов Юникод |
|
Список строк |
|
Информация о форматировании блоков текста в QTextDocument |
|
Способ определения границ текста Юникод в строке |
|
Информация о форматировании символов в QTextDocument |
|
Предоставляет API для доступа к QTextDocument и его изменения |
|
Представляет собой фрагмент форматированного текста из QTextDocument |
|
Информация о форматировании для QTextDocument |
|
Информация о форматировании кадров в QTextDocument |
|
Информация о форматировании изображений в QTextDocument |
|
Информация о форматировании списков в QTextDocument |
|
Информация о форматировании ячеек таблицы в QTextDocument |
|
Информация о форматировании таблиц в QTextDocument |
|
Удобный интерфейс для работы с URL-адресами |
|
Способ обработки пар ключ-значение в запросе URL |
|
Выступает как объединение наиболее распространенных типов данных Qt |
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.2/implicit-sharing.html