Plain Old Data Structures

21-04-2023

Перейти к: навигация, поиск

Простая структура данных (англ. plain old data, POD) — в современных языках программирования высокого уровня тип данных, имеющий жёстко определённое расположение полей в памяти, не требующий ограничения доступа и автоматического управления. Переменные такого типа можно копировать простыми процедурами копирования участков памяти наподобие memcpy. Противоположность — управляемая структура данных.

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

В стандартном Паскале и Си все типы данных являются простыми.

Преимущества простых структур данных

Простые структуры данных имеют две особенности.

Предсказуемое устройство в памяти

Компилятор может автоматически перестроить структуру данных по своему усмотрению (например, изменить порядок полей). Подобная перестройка может серьёзно сэкономить память, но нарушает совместимость. В POD’ах такая оптимизация отключена.

Другими словами: типы, отмеченные как POD, устроены в памяти в точности так, как описал программист (возможно, с некоторым выравниванием). Поэтому только POD’ы можно использовать для связи между двумя библиотеками времени выполнения. В частности — для передачи данных из программы в программу, из плагина в плагин, для связи с кодом, написанным на другом языке программирования. Чтобы быстро записать на диск сложный заголовок файла наподобие BMP, можно сформировать его в памяти, а затем записать одной командой — но структура данных, в которой формируем заголовок, также должна быть POD’ом.

Отсутствие управляющего кода

Это значит, что при появлении объекта не нужно вызывать конструктор, при копировании — операцию присваивания, а при уничтожении — деструктор. Это, в свою очередь, даёт такие преимущества.

  1. Статическая инициализация. Вместо того, чтобы при запуске программы скрытно от программиста вызывать конструктор, POD’ы можно собрать ещё при компиляции программы.
  2. Тривиальное копирование функциями наподобие memcpy.
  3. Опять-таки, это важно для связи между программами: ведь менеджер памяти не должен заниматься управлением в той памяти, которая ему не принадлежит.
  4. Только простые типы могут находиться в union (в Паскале соответственно record/case).
  5. Функции с побочным эффектом наподобие GetLastError[1] плохо совместимы с автоматически управляемыми типами.

В C++

В C++ POD определяется от противного. Тип данных является POD’ом, если:

По стандарту C++ простой тип данных устроен в точности так, как описано. Управляемую же структуру компилятор может реорганизовать так, как он сочтёт наиболее эффективным.

В C++11

«Предсказуемое устройство в памяти» и «отсутствие управляющего кода» — сходные, но разные свойства типа. Например, структуру данных STRRET,[2] которая в Windows служит для передачи строк из одного менеджера памяти в другой, можно «обернуть» в управляющий код, но второе свойство — предсказуемое устройство — остаётся. Поэтому концепция POD’ов в C++11 разделена на три.

Класс является тривиальным, если у него тривиальны:

Такие типы могут копироваться через memcpy.

Класс является типом со стандартным устройством, если:

  • все нестатические поля имеют одинаковые права доступа (все private, все protected или все public) и определены в одном классе.
  • нет виртуальных методов, виртуального наследования.
  • первое определённое поле не совпадает по типу ни с одним из родительских классов.

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

Тогда POD — это тривиальный тип по стандартным устройством, все нестатические поля которого — POD’ы.

Для работы с константами, вычисляемыми при компиляции, и статической инициализации в C++11 есть более мягкое понятие — литеральный тип. А именно:

  • либо тривиальный конструктор по умолчанию T(), либо какой-нибудь конструктор (кроме конструктора копирования и перемещения) отмечен как constexpr;
  • конструктор копирования T(T&) тривиальный;
  • конструктор перемещения T(T&&) тривиальный или запрещён;
  • тривиальный деструктор ~T();
  • унаследован от литеральных типов;
  • все его нестатические поля литеральные.

В Embarcadero Delphi

Простыми структурами данных считаются все типы, кроме:

  • новых строк неограниченной длины (AnsiString, WideString, UnicodeString);
  • интерфейсов COM;
  • динамических массивов;
  • типов, которые содержат один из этих трёх;
  • новых объектов типа class. Впрочем, TObject, TButton и т. д. — это указатели на объект и всегда являются простыми типами!

Примечания

  1. GetLastError на MSDN
  2. STRRET structure (Windows). Проверено 6 апреля 2013. Архивировано из первоисточника 18 апреля 2013.

См. также


Plain Old Data Structures.

© 2011–2023 stamp-i-k.ru, Россия, Барнаул, ул. Анатолия 32, +7 (3852) 15-49-47