Trivial class
Тривиальные классы (trivial class) - это классы или структуры, в которых специальные функции-члены предоставляются компилятором (явно отсутствует реализация) либо явно заданы как default. В таком классе нет управляющего кода, так как специальные функции-члены объявлены (явно или неявно) тривиальными по умолчанию.
Кроме того есть дополнительные требования, тривиальный класс не должен иметь:
виртуальных функций
нетривиальных базовых классов
нетривиальных типов данных
Под словом "тривиальный" понимается наличие:
тривиальных специальных функций-членов (msdn)
POD членов (см. ниже)
Тривиальные классы могут быть безопасно скопированы функциями типа memcpy в полной точности.
Тривиальность функций членов (отсутствие управляющего кода) подразумевает:
выделение памяти под объект без инициализации
побайтовое копирование объекта
освобождение памяти без очистки
// тривиальный, есть явный конструктор по умолчанию
class T0
{
public:
T0() = default;
protected:
int a;
};
// тривиальный, есть неявный конструктор по умолчанию (implicitly-defined)
class T01
{
public:
void func(){}
protected:
int a;
};
/* нетривиальный, есть инициализация члена по умолчанию
std::has_trivial_default_constructor<T1>() вернет false,
значит конструктор по умолчанию неявно обьявлен удаленным (implicitly defined as deleted)
*/
class T1
{
public:
T1() = default;
protected:
int a = 0;
};
// тривиальный, есть явный конструктор по умолчанию (explicitly defaulted)
class T2
{
public:
T2() = default;
T2(int _a){ a = _a; }
protected:
int a;
};
// нетривиальный, есть явный пользовательский конструктор (user-defined default)
class T3
{
public:
T3(){};
protected:
int a;
};
Standard layout
Стандартная структура (standard layout) - это структура (struct), которая не содержит специальных возможностей C++:
виртуальные функции и виртуальные базовые классы
несколько уровней доступа (private, protected)
нестатические члены ссылочного типа
Стандартная структура:
не имеет члены являющиеся нестандартной структурой
не имеет базовые классы не являющиеся нестандартной структурой
не имеет более одного базового класса с нестатическими членами данных
не имеет двух мест обьявления нестатических членов (например в базовом классе и у себя)
не имеет более двух базовых (или косвенно) классов
Стандартная структура имеет предсказуемое устройство памяти, так как не содержит данных, которые компилятор мог бы структурировать по своему усмотрению (например в случае наличия public/private/protected) - как написано так и храниться в памяти.
// standard layout
struct Test1
{
int a;
};
// standard layout
struct Test2
{
void Foo(){}
};
// standard layout
struct Test3
{
int a2;
void Foo3(){}
};
/* non standard layout,
первый нестатичный член такой же как и базовый класс
*/
struct Test4 : Test1
{
Test1 a2;
};
/* standard layout,
теперь нестатичный член a3 типа Test2
(как и базовый тип этой структуры) не является первым
*/
struct Test5 : Test2
{
Test3 a2;
Test2 a3;
};
// standard layout
struct Test12 : Test1, Test2
{};
/* non standard layout,
третий базовый класс недопустим
*/
struct Test123 : Test1, Test2, Test3
{};
/*non standard layout,
2 места обьявления нестатических члена в Test1 и в Test12_1
*/
struct Test12_1 : Test1, Test2
{
int b;
};
// standard layout
struct Test12_2 : Test1, Test2
{
void Foo2(){}
};
POD (Plain Old Data - обычные старые данные) - тип данных являющий скаляром или одновременно тривиальным классом, стандартной структурой и агрегатным типом. Совместим с C, с возможностью копирования объекта функциями типа memcpy.
POD обладает сразу двумя свойствами:
отсутствие управляющего кода (тривиальный класс)
предсказуемое устройство памяти (стандартная структура)
struct POD
{
int a;
int b;
};
Автор: Виталий Бутурлин