Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Intrusive and non-intrusive containers

Boost , The Boost C++ Libraries BoostBook Documentation Subset , Chapter 17. Boost.Intrusive

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Основное различие между интрузивными контейнерами и неинтрузивными контейнерами заключается в том, что в C++ неинтрузивные контейнеры хранятся.копиизначений, переданных пользователем. Контейнеры используют шаблонный параметр<Allocator>для распределения хранимых значений:

#include <list>
#include <assert.h>
int main()
{
   std::list<MyClass> myclass_list;
   MyClass myclass(...);
   myclass_list.push_back(myclass);
   //The stored object is different from the original object
   assert(&myclass != &myclass_list.front());
   return 0;
}

Для хранения вновь выделенной копии<myclass>контейнеру нужны дополнительные данные:<std::list>обычно выделяет узлы, содержащие указатели на следующий и предыдущий узел и само значение. Нечто похожее на:

//A possible implementation of a std::list<MyClass> node
class list_node
{
   list_node *next;
   list_node *previous;
   MyClass    value;
};

С другой стороны, интрузивный контейнер не хранит копии пропущенных предметов, а хранит сами объекты. Дополнительные данные, необходимые для вставки объекта в контейнер, должны быть предоставлены самим объектом. Например, чтобы вставить<MyClass>в навязчивый контейнер, который реализует связанный список,<MyClass>должен содержать необходимыеследующиеипредыдущиеуказатели:

class MyClass
{
   MyClass *next;
   MyClass *previous;
   //Other members...
};
int main()
{
   acme_intrusive_list<MyClass> list;
   MyClass myclass;
   list.push_back(myclass);
   //"myclass" object is stored in the list
   assert(&myclass == &list.front());
   return 0;
}

Как видим, знать, какие дополнительные данные должен содержать класс, непростая задача.Boost.Intrusiveпредлагает несколько интрузивных контейнеров и простой способ сделать классы пользователей совместимыми с этими контейнерами.

Семантически контейнерBoost.Intrusiveпохож на контейнер STL, содержащий указатели на объекты. То есть, если у вас есть навязчивый список, содержащий объекты типа<T>, то<std::list<T*>>позволит вам делать совершенно те же операции (поддержание и навигация набора объектов типа Т и типов, полученных из него).

Неинтрузивный контейнер имеет некоторые ограничения:

  • Объект может принадлежать только одному контейнеру: Если вы хотите разделить объект между двумя контейнерами, вам нужно либо хранить несколько копий этих объектов, либо использовать контейнеры с указателями:<std::list<Object*>>.
  • Использование динамического распределения для создания копий переданных значений может быть узким местом производительности и размера в некоторых приложениях. Обычно динамическое распределение накладывает накладные расходы по размеру для каждого распределения для хранения бухгалтерской информации и синхронизации для защищенного одновременного распределения из разных потоков.
  • Только копии объектов хранятся в ненавязчивых контейнерах. Следовательно, требуются конструкторы копирования или перемещения и операторы присваивания копирования или перемещения. Некопируемые и неподвижные объекты не могут храниться в неинтрузивных контейнерах.
  • Невозможно хранить полученный объект в STL-контейнере, сохраняя его первоначальный тип.

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

  • Работа с назойливыми контейнерами вообще не требует управления памятью. Накладные расходы на время и размер, связанные с динамической памятью, могут быть сведены к минимуму.
  • Итерация Интрузивного контейнера требует меньшего доступа к памяти, чем семантически эквивалентный контейнер указателей: итерация быстрее.
  • Интрузивные контейнеры предлагают лучшие гарантии исключения, чем неинтрузивные контейнеры. В некоторых ситуациях интрузивные контейнеры предлагают гарантию отсутствия броска, которая не может быть достигнута с неинтрузивными контейнерами.
  • Вычисление итератора к элементу из указателя или ссылки на этот элемент представляет собой постоянную операцию времени (вычисление положения<T*>в<std::list<T*>>имеет линейную сложность).
  • Интрузивные контейнеры обеспечивают предсказуемость при вставке и стирании объектов, поскольку управление памятью не осуществляется с помощью интрузивных контейнеров. Управление памятью обычно не является предсказуемой операцией, поэтому гарантии сложности от неинтрузивных контейнеров являются более слабыми, чем гарантии, предлагаемые интрузивными контейнерами.

Инвазивные контейнеры также имеют недостатки:

  • Каждый тип, хранящийся в инвазивном контейнере, нуждается в дополнительной памяти, содержащей информацию об обслуживании, необходимую контейнеру. Следовательно, всякий раз, когда определенный тип будет храниться в навязчивом контейнере, вы должны соответствующим образом изменить определение этого типа. Хотя эта задача проста сBoost.Intrusive, касание определения типа иногда является важным вопросом.
  • В назойливых контейнерах вы не храните копию объекта, а скорее оригинальный объект связан с другими объектами в контейнере. Объекты не нуждаются в копи-конструкторах или операторах назначения для хранения в навязчивых контейнерах. Но нужно позаботиться о возможных побочных эффектах, когда вы меняете содержимое объекта (это особенно важно для ассоциативных контейнеров).
  • Пользовательдолжен управлять временем жизни вставленных объектовнезависимо от контейнеров.
  • Опять же, вы должны бытьосторожны: в отличие от контейнеров STLлегко сделать итератор недействительным, не касаясь непосредственно назойливого контейнера, потому что объект может быть удален до того, как он будет стерт из контейнера.
  • Навязчивыеконтейнерыне поддаются копированию и не поддаются передаче. Поскольку интрузивные контейнеры не имеют возможности распределения, эти операции не имеют смысла. Однако замена может использоваться для реализации возможностей перемещения. Для облегчения реализации копировальных конструкторов и назначения операторов классов храненияBoost.Intrusiveконтейнеров,Boost.Intrusiveпредлагает специальные функции клонирования. См.Клонирование. Инвазивные контейнерыраздел для получения дополнительной информации.
  • Анализ безопасности потока программы, использующей контейнеры, сложнее с использованием интрузивных контейнеров, поскольку контейнер может быть изменен косвенно без явного вызова контейнера.

Table 17.1. Summary of intrusive containers advantages and disadvantages

Вопрос

навязчивый

неинтрузивный

Управление памятью

Внешний

Внутренний через распределитель

Время вставки/удаления

Быстрее

Медленнее

Локальность памяти

Лучше

Хуже

Может содержать некопируемые и неподвижные объекты по стоимости

Да

Нет

Гарантии исключения

Лучше

Хуже

Вычисление итератора из значения

Константа

Непостоянный

Предсказуемость включения/стирания

Высоко

Низкий

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

Минимальный

Больше, чем минимум

Вставить объекты, сохраняющие полиморфное поведение

Да

Нет

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

Да

Нет

Контейнеры копируются

Нет

Да

Встроенный объект, управляемый

Пользователь (более сложный)

Контейнер (менее сложный)

Инварианты контейнера можно разбить без использования контейнера

Легче

Более жесткие (только с контейнерами указателей)

Анализ безопасности потока

Сильнее

Легче


Сравнение производительности между интрузивными и неинтрузивными контейнерами см. в разделеПроизводительность.


PrevUpHomeNext

Статья Intrusive and non-intrusive containers раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 17. Boost.Intrusive может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Chapter 17. Boost.Intrusive ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 17:34:47/0.0086188316345215/0