Макет - це спосіб розташування членів об’єкта класу, структури або об’єднання в пам’яті. Це може бути суперечливим чи ні. Досить часто мова вказує макет, але якщо є щось на зразок віртуальної функції, віртуального базового класу тощо, то компілятор може вільно вибирати макет, і це може бути не суцільним. Це призводить до кількох проблем, через які ми не можемо належним чином серіалізувати об'єкт або передати його програмам, написаним іншими мовами, як-от C, або таким функціям, як memcopy, оскільки ми не можемо надійно скопіювати дані, які перебувають не в сусідніх місцях.
Щоб дозволити компіляторам та програмам c ++ підтримувати вищезазначені операції, c ++ представив 3 категорії для простих структур та класів.
Тривіальний
Клас або структура є тривіальними, якщо вони відповідають правилам:
- відсутність віртуальної функції або віртуального базового класу
- відсутність визначеного користувачем конструктора / оператора / деструктора
- базовий клас повинен бути тривіальним
- всі учасники класу повинні бути дріб’язковими
Якщо клас є тривіальним, то його макет є суперечливим, але може бути відповідно заповнення, і компілятор може вільно вибирати порядок членів у макеті. Тому, хоча ми можемо скопіювати об’єкт, це не є надійним, якщо ми скопіюємо цей об’єкт до програми C. Ми можемо мати різні специфікатори доступу в одному і тому ж класі, і якщо ми використовуємо параметризований конструктор, ми, очевидно, маємо вказати конструктор за замовчуванням. Але якщо ви хочете зберегти клас тривіальним, вам слід явно зробити конструктор за замовчуванням. Конструктори повинні бути загальнодоступними.
Стандартний макет
- Немає віртуальних функцій і віртуального базового класу
- Усі нестатичні члени повинні мати однакові специфікатори доступу
- Усі нестатичні члени повинні мати стандартний макет
- Усі базові класи повинні мати стандартний макет
- Усі члени базового класу повинні бути статичними
- Тип базового класу та першого нестатичного члена класу не повинні бути однаковими
Стандартний макет чітко визначений, і його можна надійно скопіювати та передати відповідним чином програмам C. Також стандартні функції компонування можуть мати визначені користувачем спеціальні функції-члени, такі як конструктор та деструктор.
POD (звичайні старі дані)
Якщо клас або структура є як тривіальним, так і стандартним макетом, тоді він називається POD.Кожний член зберігається в порядку, вказаному при оголошенні об'єкта. Класи POD повинні мати нестатичні члени даних POD. Класи POD можна копіювати або надійно передавати програмам C.
Програма C ++ із класом, який є тривіальним, стандартним макетом і, отже, POD.
#include<iostream>
#include<type_traits>
class xyz
{
public:
int a;
int b;
xyz() = default;
xyz(int x, int y) :a(x), b(y) {}
};
int main() {
std::cout << std::is_trivial<xyz>() << std::endl;
std::cout << std::is_standard_layout<xyz>() << std::endl;
std::cout << std::is_pod<xyz>() << std::endl;
}
Літеральні типи
Для буквеного типу макет можна визначити під час компіляції. Приклади буквених типів порожні, скалярні типи, такі як int, float тощо, посилання, масиви void, скалярні типи або посилання та клас A, який має тривіальний деструктор, і один або кілька конструкторів constexpr, які не є конструкторами переміщення або копіювання. Крім того, усі його нестатичні члени даних та базові класи повинні бути буквальними типами та не мінливими