Домашняя страница POD типы в C++
Публикация
Отменить

POD типы в C++

POD типы в языке C++ это аббревиатура от “Plain Old Data”, что можно трактовать как «Простые данные в стиле C».

Все типы делятся на две группы: объектные типы и все остальные. К не объектным типам относятся функции, ссылки и тип void. У таких типов, нельзя узнать размер с помощью операции sizeof.

Группа объектных типов содержит две подгруппы – POD и не-POD типы.

К POD-типам относятся:

  1. все встроенные арифметические типы (включая wchar_t и bool);
  2. перечисления, т.е. типы, объявленные с помощью ключевого слова enum;
  3. указатели;
  4. POD-структуры (struct или class) и POD-объединения (union);

Чтобы структура была POD-типом, она должна удовлетворять следующим требованиям:

  1. не иметь пользовательских конструкторов, деструктора или копирующего оператора присваивания;
  2. не иметь базовых классов;
  3. не иметь виртуальных функций;
  4. не иметь защищенных (protected) или закрытых (private) нестатических членов данных;
  5. не иметь не статических членов данных не-POD-типов (или массивов из таких типов), а также ссылок.

Копирующий оператор присваивания – это такой не шаблонный нестатический operator=, у которого есть строго один параметр типа X, X&, const X&, volatile X& или const volatile X&, где X – тип рассматриваемой структуры или объединения).

Все оставшиеся объектные типы являются не-POD-типами. Наличие квалификаторов const и volatile не влияет на «POD-овость» типа.

Работа с типами

POD типы были введены чтобы разделить работу со старыми типами языка С и новыми в С++. При работе с POD типами известно их размещение в памяти, а так же работают все средства из С. Например можно пользоваться функциями memset, memcopy.

Для не-POD-типа нельзя сделать практически никаких предположений о том, как устроен объект. Внутри такого объекта в (практически) произвольном месте могут располагаться служебные области, не подконтрольные программисту. Это было сделано для того, чтобы разработчики компилятора могли организовывать новые типы по своему усмотрению, из соображений эффективности реализации.

Рассмотрим следующий пример:

1
2
3
4
5
6
7
8
9
10
11
12
struct SomeType
{
  char c;
  int i;
// protected:
  char sz[10];
} s1, s2;
 
&s1 == &s1.c; // (1) всегда истина
&s1.i == &s1.c + 1 + выравнивание; // (2) всегда истина
&s1.i > &s1.c; // (3) всегда истина
&s1.sz > &s1.i; // (4) всегда истина

Данная структура является POD типом и для нее справедливы все приведенные утверждения.

Во многих компиляторах формат представления в памяти объекта из данного примера не изменится, если раскомментировать “//protected:” и все приведенные операции будут продолжать работать по-прежнему, но тем не менее, Стандартом С++ это не гарантируется (кроме условия (3)).

С другой стороны, добавление виртуальной функции, например, практически на всех компиляторах вызовет нарушение (1). Вообщем, лучше полагаться на Стандарт, и всегда избегать делать предположения о представлении объекта не-POD типа в памяти.

Комментарии

dragonmaster, 17 мая 2011, 14:58

енумераторы (enum) по-русски называются «перечисления»…

Публикация защищена лицензией CC BY 4.0 .