Что такое типы POD в C ++?

Я несколько раз сталкивался с этим термином POD-type. Что это значит?

POD означает « Обычные старые данные», то есть class (независимо от того, задано ли это ключевое слово struct или class ключевого слова) без конструкторов, деструкторов и функций виртуальных членов. Статья Википедии о POD идет более подробно и определяет ее как:

Обычная структура старых данных в C ++ – это совокупный class, который содержит только PODS в качестве членов, не имеет определяемого пользователем деструктора, не определенного пользователем оператора назначения копирования и нестационарных членов типа «указатель-член».

Более подробную информацию можно найти в этом ответе для C ++ 98/03 . C ++ 11 изменил правила, связанные с POD, сильно расслабив их, что вызвало необходимость последующего ответа .

Очень неформально:

POD – это тип (включая classы), где компилятор C ++ гарантирует, что в структуре не будет «волшебства»: например, скрытые указатели на vtables, смещения, которые применяются к адресу, когда он передается другим типам (например, по крайней мере, если POD цели тоже), конструкторы или деструкторы. Грубо говоря, тип – это POD, когда единственные вещи в нем – это встроенные типы и их комбинации. Результатом является то, что «действует как« тип C ».

Менее неофициально:

  • int , char , wchar_t , bool , float , double – это POD, а также long/short и signed/unsigned версии.
  • указатели (включая указатель на функцию и указатель на элемент) – это POD,
  • enums – это POD
  • const или volatile POD – это POD.
  • class , struct или union POD – это POD, при условии, что все нестатические члены данных являются public и не имеют базового classа и конструкторов, деструкторов или виртуальных методов. Статические члены не останавливают что-то, являющееся POD в соответствии с этим правилом.
  • Википедия ошибается, заявив, что POD не может иметь членов типа указатель-к-член. Вернее, это правильно для формулировки C ++ 98, но TC1 четко указал, что указатели на член POD.

Формально (стандарт C ++ 03):

3.9 (10): «Арифметические типы (3.9.1), типы enums, типы указателей и указатели на типы членов (3.9.2) и cv-квалификационные версии этих типов (3.9.3) являются совокупно вызывающими скалярными типами. типы, типы POD-структуры, типы POD-соединения (раздел 9), массивы таких типов и cv-квалификационные версии этих типов (3.9.3) совместно называются типами POD ”

9 (4): «POD-struct – это совокупный class, который не имеет нестатических членов данных типа non-POD-struct, non-POD-union (или массив таких типов) или ссылки, определить оператор копирования и не определяемый пользователем деструктор. Аналогично, POD-union представляет собой совокупный союз, в котором не используются нестатические члены данных типа non-POD-struct, non-POD-union (или массив таких типов) или ссылки, и не имеет пользовательского оператора копирования и не определяется пользователем деструктором.

8.5.1 (1): «Агрегат – это массив или class (раздел 9) без конструкторов, объявленных пользователем (12.1), без частных или защищенных нестатических элементов данных (раздел 11), без базовых classов (раздел 10) и нет виртуальных функций (10.3) ».

Обычные старые данные

Короче говоря, это все встроенные типы данных (например, int , char , float , long , unsigned char , double и т. Д.) И вся совокупность данных POD. Да, это рекурсивное определение. 😉

Чтобы быть более понятным, POD – это то, что мы называем «структурой»: единица или группа единиц, которые просто хранят данные.

Насколько я понимаю, POD (PlainOldData) – это просто необработанные данные – он не нужен:

  • который будет построен,
  • быть уничтоженным,
  • иметь пользовательские операторы.
  • Не должно быть виртуальных функций,
  • и не должны переопределять операторов.

Как проверить, является ли что-то POD? Ну, есть структура, которая называется std::is_pod :

 namespace std { // Could use is_standard_layout && is_trivial instead of the builtin. template struct is_pod : public integral_constant { }; } 

(Из заголовка type_traits)

Справка:

Объект POD (простые старые данные) имеет один из этих типов данных – фундаментальный тип, указатель, объединение, структура, массив или class – без конструктора. И наоборот, объект не-POD – это объект, для которого существует конструктор. Объект POD начинает свою жизнь, когда он получает хранилище с соответствующим размером для своего типа, а его срок службы заканчивается, когда хранилище для объекта повторно используется или освобождается.

В типах PlainOldData также не должно быть:

  • Виртуальные функции (либо собственные, либо унаследованные)
  • Виртуальные базовые classы (прямые или косвенные).

Более слабое определение PlainOldData включает объекты с конструкторами; но исключает тех, у кого есть виртуальное. Важная проблема с типами PlainOldData заключается в том, что они не являются полиморфными. Наследование может быть выполнено с помощью типов POD, однако это должно быть сделано только для реализацииInheritance (повторное использование кода), а не для polymorphismа / подтипирования.

Обычное (хотя и не строго правильное) определение состоит в том, что тип PlainOldData – это все, что не имеет VeeTable.

Концепция POD и черта типа std::is_pod будет устаревать в C ++ 20. См. Этот вопрос для получения дополнительной информации.

С C ++ Plain Old Data не просто означает, что такие вещи, как int, char и т. Д., Являются единственными используемыми типами. Обычные старые данные на самом деле означает, что вы можете взять структуру memcpy из одного места в памяти в другое, и все будет работать точно так, как вы ожидали бы (т.е. не взорвать). Это прерывается, если ваш class или любой class, который содержит ваш class, имеет член, который является указателем или ссылкой или classом, который имеет виртуальную функцию. По существу, если указатели должны быть задействованы где-то, это не обычные старые данные.

  • Разница между и
  • Разница между типами string и char в C ++
  • java: конвертировать float в String и String для float
  • Как изменить тип данных DataColumn в DataTable?
  • Почему некоторые люди предпочитают «T const &» над «const T &»?
  • Преобразование hex в текстовое представление в десятичное число
  • Преобразовать строку в тип C #
  • Где в памяти мои переменные, хранящиеся в C?
  • Строка к двоичной в C #
  • «Неполный тип» в classе, который имеет один и тот же тип самого classа
  • Как определить тип MIME загруженного файла в ASP.NET?
  • Давайте будем гением компьютера.