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