聚合类型&POD

什么是聚合类型

C++03定义
An aggregate is an array or a class (clause 9) with no user-declared constructors (12.1), no private or protected non-static data members (clause 11), no base classes (clause 10), and no virtual functions (10.3).

C++11定义
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal-initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

结合C++03和C++11标准定义,罗列一下聚合类型的特性:

  • 聚合类型可以有构造函数,但只能是编译器定义的默认构造函数,或者用=default定义的构造函数
  • 聚合类型不能有private,protected非static变量
  • 聚合类型可以有copy-assignment operator and/or destructor
  • 数组是聚合类型,即便数组成员是非聚合类型
  • 聚合类型的数组可以是非聚合类型
  • 聚合类型不能用brace-or-equal-initializers(即就地初始化)初始化非static成员。

聚合类型变量初始化

聚合类型可以采用列表初始化(其实非聚合类型,通过自定义构造函数,也可以采用列表初始化)

if(m == n)
{
    // the ith element of the array is initialized with ai
}
else if(m < n) {
    // the first m elements of the array are initialized with a1,  a2, …, am and the other n - m elements are, if possible, value-initialized (see below for the explanation of the term)
}
else if(m > n) {
    // the compiler will issue an error
}
else /*(this is the case when n isn't specified at all like int a[] = {1, 2, 3};) */
{
    // the size of the array (n) is assumed to be equal to m, so int a[] = {1, 2, 3}; is equivalent to int a[3] = {1, 2, 3};
}

聚合变量最大的特点可以做聚合初始化,除了基本的列表初始化规则,聚合初始化还体现在可以递归初始化。

struct X
{
  int i1;
  int i2;
};
struct Y
{
  char c;
  X x;
  int i[2];
  float f; 
protected:
  static double d;
private:
  void g(){}      
}; 
struct Z {
  char a;
  X x;
  Z(char a1) {};
};

Y y = {'a', {10, 20}, {20, 30}};

y.x也被初始化了。如果对Z用递归聚合初始化,例如Z z = {'a', {'b'}},编译器就会报错。因为Z不是聚合类型,编译器会去找对应的构造函数,显然Z没定义这样的构造函数。
具体介绍可以参考Aggregate initialization

什么是POD变量

POD = Plain Old Data,可见这是一种兼容型比较好的形态。甚至可以导出与其他语言共享此类变量定义。

C++03定义
A POD-struct is an aggregate class that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no user-defined copy assignment operator and no user-defined destructor. Similarly, a POD-union is an aggregate union that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no user-defined copy assignment operator and no user-defined destructor. A POD class is a class that is either a POD-struct or a POD-union.

C++11定义变得非常优雅
A POD struct is a non-union class that is both a trivial class and a standard-layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types). Similarly, a POD union is a union that is both a trivial class and a standard layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types). A POD class is a class that is either a POD struct or a POD union.

总而言之:
POD类型是一种特殊的聚合类型,一个POD类型为:

  • 标量类型。
  • 满足以下条件的自定义类型:
    • C++11之前:
      • 聚合类型。
      • 没有非POD类型的非静态成员变量。
      • 没有引用类型的非静态成员变量。
      • 没有自定义的构造函数或析构函数。
    • C++11之后:
      • 是平凡类。
      • 是标准布局类。
      • 没有非POD类型的非静态成员变量。
  • POD类型的数组。

聚合类型或是POD变量有什么好处?

聚合类最大的特点就是可以采用聚合初始化。
POD的特点更为实用一些

POD的用途
平凡类的用途:

  • 平凡类的对象可以与字节流之间安全转换,即:
    - 若要将对象转为字节流,直接取其地址即可。
    - 若要将字节流转为对象,直接将该地址cast为对象指针即可。
    - 直接通过复制字节的方式复制对象。
  • 安全的静态初始化。
    - C++11的thread_local变量可以是非平凡类型,但在某些编译器下会有比较大的性能开销。gcc扩展的__thread只能使用POD类型。

标准布局类的用途:
跨进程、跨语言使用。

名次解释

value initialization

  • 对于普通类型变量(bool, int, char, double, pointers, etc.)
    it means it is initialized with 0 for that type (false for bool, 0.0 for double, etc.).
  • 对于class类型
    • 如果有自定义构造函数,则调用自定义构造函数
    • 如果没有自定一构造函数,则调用默认构造函数
    • 如果没有对应的构造函数,则报错

举例

class A
{
public:
  A(int) {} //no default constructor
};
class B
{
public:
  B() {} //default constructor available
};
int main()
{
  A a1[3] = {A(2), A(1), A(14)}; //OK n == m
  A a2[3] = {A(2)}; //ERROR A has no default constructor. Unable to value-initialize a2[1] and a2[2]
  B b1[3] = {B()}; //OK b1[1] and b1[2] are value initialized, in this case with the default-ctor
  int Array1[1000] = {0}; //All elements are initialized with 0;
  int Array2[1000] = {1}; //Attention: only the first element is 1, the rest are 0;
  bool Array3[1000] = {}; //the braces can be empty too. All elements initialized with false
  int Array4[1000]; //no initializer. This is different from an empty {} initializer in that
  //the elements in this case are not value-initialized, but have indeterminate values 
  //(unless, of course, Array4 is a global array)
  int array[2] = {1, 2, 3, 4}; //ERROR, too many initializers
}

大括号中个数不足的,用value initialization补足。这就是A a = {1};或者A a = {}的含义。大括号中个数超过声明的个数的,则编译报错。

brace-or-equal-initializers

类成员的一种初始化方法

class B {
public:
    B(int){}
};

class A {
    int a = 123;
    int b {456};
    B c {12};
    B d = {34};
};

copy-assignment operator

拷贝赋值方法

class A {
    A A(int) {}
    A(const &) {}
    A& operator= (const A&a) {}
};
void main() {
    A a;
    A b = a; // 这里调用的是拷贝构造函数
    A c;
    c = a; // 这里才会调用拷贝复制函数
}

trial stuff

trivial copyable

参考C++ named requirements: TriviallyCopyable

The following types are collectively called trivially copyable types:

  • Scalar types
  • Trivially copyable classes, i.e. classes satisfying following requirements:
    - At least one copy constructor, move constructor, copy assignment operator, or move assignment operator is eligible
    - Every eligible copy constructor (if any) is trivial
    - Every eligible move constructor (if any) is trivial
    - Every eligible copy assignment operator (if any) is trivial
    - Every eligible move assignment operator (if any) is trivial
    - Has a trivial non-deleted destructor
  • Arrays of TriviallyCopyable objects

This implies that a trivially copyable class has no virtual functions or virtual base classes.

通过模版std::is_trivially_copyable可以检验一个类是否trivially copyable。

trivial constructor/destructor

  • 编译器定义的构造/析构函数
  • =default定义的构造析构函数

trivial class

The standard defines a trivial class as follows:

A trivially copyable class is a class that:

  • has no non-trivial copy constructors (12.8),
  • has no non-trivial move constructors (12.8),
  • has no non-trivial copy assignment operators (13.5.3, 12.8),
  • has no non-trivial move assignment operators (13.5.3, 12.8), and
  • has a trivial destructor (12.4).

A trivial class is a class that has a trivial default constructor (12.1) and is trivially copyable.

[ Note: In particular, a trivially copyable or trivial class does not have virtual functions or virtual base classes. ]
另外trivial class是递归的,即trivial class不能有非trivial class的非static成员。
用模版std::is_trivial来测试

standard layout

A standard-layout class is a class that:

  • has no non-static data members of type non-standard-layout class (or array of such types) or reference,

  • has no virtual functions (10.3) and no virtual base classes (10.1),

  • has the same access control (Clause 11) for all non-static data members,

  • has no non-standard-layout base classes,

  • either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, (要么终点类没有非静态成员,并且只有一个基类有非静态成员;要么没有基类有非静态成员),and

  • has no base classes of the same type as the first non-static data member.

A standard-layout struct is a standard-layout class defined with the class-key struct or the class-key class.

A standard-layout union is a standard-layout class defined with the class-key union.

[ Note: Standard-layout classes are useful for communicating with code written in other programming languages. Their layout is specified in 9.2.]

标准内存分布,确保对象内存和C语言的结构体内存分布完全一致。使得POD变量具备了C兼容性。
用模版std::is_standard_layout可以测试

总结

std::is_pod来测试你的类吧。

参考文献

  1. What are Aggregates and PODs and how/why are they special?
  2. C++对象模型(三)POD
%23%20%E4%BB%80%E4%B9%88%E6%98%AF%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%0A%3E%20**C%2B%2B03%E5%AE%9A%E4%B9%89**%0A%3E%20An%20aggregate%20is%20an%20array%20or%20a%20class%20(clause%209)%20with%20no%20user-declared%20constructors%20(12.1)%2C%20no%20private%20or%20protected%20non-static%20data%20members%20(clause%2011)%2C%20no%20base%20classes%20(clause%2010)%2C%20and%20no%20virtual%20functions%20(10.3).%0A%0A%3E%20**C%2B%2B11%E5%AE%9A%E4%B9%89**%0A%3E%20An%20aggregate%20is%20an%20array%20or%20a%20class%20(Clause%209)%20with%20no%20user-provided%20constructors%20(12.1)%2C%20no%20brace-or-equal-initializers%20for%20non-static%20data%20members%20(9.2)%2C%20no%20private%20or%20protected%20non-static%20data%20members%20(Clause%2011)%2C%20no%20base%20classes%20(Clause%2010)%2C%20and%20no%20virtual%20functions%20(10.3).%0A%0A%E7%BB%93%E5%90%88C%2B%2B03%E5%92%8CC%2B%2B11%E6%A0%87%E5%87%86%E5%AE%9A%E4%B9%89%EF%BC%8C%E7%BD%97%E5%88%97%E4%B8%80%E4%B8%8B%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%E7%9A%84%E7%89%B9%E6%80%A7%EF%BC%9A%0A-%20%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%E5%8F%AF%E4%BB%A5%E6%9C%89%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%EF%BC%8C%E4%BD%86%E5%8F%AA%E8%83%BD%E6%98%AF%E7%BC%96%E8%AF%91%E5%99%A8%E5%AE%9A%E4%B9%89%E7%9A%84%E9%BB%98%E8%AE%A4%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%EF%BC%8C%E6%88%96%E8%80%85%E7%94%A8%60%3Ddefault%60%E5%AE%9A%E4%B9%89%E7%9A%84%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%0A-%20%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%E4%B8%8D%E8%83%BD%E6%9C%89private%EF%BC%8Cprotected%E9%9D%9Estatic%E5%8F%98%E9%87%8F%0A-%20%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%E5%8F%AF%E4%BB%A5%E6%9C%89copy-assignment%20operator%20and%2For%20destructor%0A-%20%E6%95%B0%E7%BB%84%E6%98%AF%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%EF%BC%8C%E5%8D%B3%E4%BE%BF%E6%95%B0%E7%BB%84%E6%88%90%E5%91%98%E6%98%AF%E9%9D%9E%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%0A-%20%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%95%B0%E7%BB%84%E5%8F%AF%E4%BB%A5%E6%98%AF%E9%9D%9E%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%0A-%20%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%E4%B8%8D%E8%83%BD%E7%94%A8brace-or-equal-initializers%EF%BC%88%E5%8D%B3%E5%B0%B1%E5%9C%B0%E5%88%9D%E5%A7%8B%E5%8C%96%EF%BC%89%E5%88%9D%E5%A7%8B%E5%8C%96%E9%9D%9Estatic%E6%88%90%E5%91%98%E3%80%82%0A%0A%23%23%20%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%E5%8F%98%E9%87%8F%E5%88%9D%E5%A7%8B%E5%8C%96%0A%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%E5%8F%AF%E4%BB%A5%E9%87%87%E7%94%A8%E5%88%97%E8%A1%A8%E5%88%9D%E5%A7%8B%E5%8C%96%EF%BC%88%E5%85%B6%E5%AE%9E%E9%9D%9E%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%EF%BC%8C%E9%80%9A%E8%BF%87%E8%87%AA%E5%AE%9A%E4%B9%89%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%EF%BC%8C%E4%B9%9F%E5%8F%AF%E4%BB%A5%E9%87%87%E7%94%A8%E5%88%97%E8%A1%A8%E5%88%9D%E5%A7%8B%E5%8C%96%EF%BC%89%0A%60%60%60%20c%0Aif(m%20%3D%3D%20n)%0A%7B%0A%20%20%20%20%2F%2F%20the%20ith%20element%20of%20the%20array%20is%20initialized%20with%20ai%0A%7D%0Aelse%20if(m%20%3C%20n)%20%7B%0A%20%20%20%20%2F%2F%20the%20first%20m%20elements%20of%20the%20array%20are%20initialized%20with%20a1%2C%20%20a2%2C%20%E2%80%A6%2C%20am%20and%20the%20other%20n%20-%20m%20elements%20are%2C%20if%20possible%2C%20value-initialized%20(see%20below%20for%20the%20explanation%20of%20the%20term)%0A%7D%0Aelse%20if(m%20%3E%20n)%20%7B%0A%20%20%20%20%2F%2F%20the%20compiler%20will%20issue%20an%20error%0A%7D%0Aelse%20%2F*(this%20is%20the%20case%20when%20n%20isn't%20specified%20at%20all%20like%20int%20a%5B%5D%20%3D%20%7B1%2C%202%2C%203%7D%3B)%20*%2F%0A%7B%0A%20%20%20%20%2F%2F%20the%20size%20of%20the%20array%20(n)%20is%20assumed%20to%20be%20equal%20to%20m%2C%20so%20int%20a%5B%5D%20%3D%20%7B1%2C%202%2C%203%7D%3B%20is%20equivalent%20to%20int%20a%5B3%5D%20%3D%20%7B1%2C%202%2C%203%7D%3B%0A%7D%0A%60%60%60%0A%E8%81%9A%E5%90%88%E5%8F%98%E9%87%8F%E6%9C%80%E5%A4%A7%E7%9A%84%E7%89%B9%E7%82%B9%E5%8F%AF%E4%BB%A5%E5%81%9A**%E8%81%9A%E5%90%88%E5%88%9D%E5%A7%8B%E5%8C%96**%EF%BC%8C%E9%99%A4%E4%BA%86%E5%9F%BA%E6%9C%AC%E7%9A%84%E5%88%97%E8%A1%A8%E5%88%9D%E5%A7%8B%E5%8C%96%E8%A7%84%E5%88%99%EF%BC%8C%E8%81%9A%E5%90%88%E5%88%9D%E5%A7%8B%E5%8C%96%E8%BF%98%E4%BD%93%E7%8E%B0%E5%9C%A8%E5%8F%AF%E4%BB%A5%E9%80%92%E5%BD%92%E5%88%9D%E5%A7%8B%E5%8C%96%E3%80%82%0A%60%60%60c%2B%2B%0Astruct%20X%0A%7B%0A%20%20int%20i1%3B%0A%20%20int%20i2%3B%0A%7D%3B%0Astruct%20Y%0A%7B%0A%20%20char%20c%3B%0A%20%20X%20x%3B%0A%20%20int%20i%5B2%5D%3B%0A%20%20float%20f%3B%20%0Aprotected%3A%0A%20%20static%20double%20d%3B%0Aprivate%3A%0A%20%20void%20g()%7B%7D%20%20%20%20%20%20%0A%7D%3B%20%0Astruct%20Z%20%7B%0A%20%20char%20a%3B%0A%20%20X%20x%3B%0A%20%20Z(char%20a1)%20%7B%7D%3B%0A%7D%3B%0A%0AY%20y%20%3D%20%7B'a'%2C%20%7B10%2C%2020%7D%2C%20%7B20%2C%2030%7D%7D%3B%0A%60%60%60%0A%60y.x%60%E4%B9%9F%E8%A2%AB%E5%88%9D%E5%A7%8B%E5%8C%96%E4%BA%86%E3%80%82%E5%A6%82%E6%9E%9C%E5%AF%B9Z%E7%94%A8%E9%80%92%E5%BD%92%E8%81%9A%E5%90%88%E5%88%9D%E5%A7%8B%E5%8C%96%EF%BC%8C%E4%BE%8B%E5%A6%82%60Z%20z%20%3D%20%7B'a'%2C%20%7B'b'%7D%7D%60%EF%BC%8C%E7%BC%96%E8%AF%91%E5%99%A8%E5%B0%B1%E4%BC%9A%E6%8A%A5%E9%94%99%E3%80%82%E5%9B%A0%E4%B8%BAZ%E4%B8%8D%E6%98%AF%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%EF%BC%8C%E7%BC%96%E8%AF%91%E5%99%A8%E4%BC%9A%E5%8E%BB%E6%89%BE%E5%AF%B9%E5%BA%94%E7%9A%84%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%EF%BC%8C%E6%98%BE%E7%84%B6Z%E6%B2%A1%E5%AE%9A%E4%B9%89%E8%BF%99%E6%A0%B7%E7%9A%84%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E3%80%82%0A%E5%85%B7%E4%BD%93%E4%BB%8B%E7%BB%8D%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%5BAggregate%20initialization%5D(https%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Flanguage%2Faggregate_initialization)%E3%80%82%0A%23%20%E4%BB%80%E4%B9%88%E6%98%AFPOD%E5%8F%98%E9%87%8F%0APOD%20%3D%20Plain%20Old%20Data%EF%BC%8C%E5%8F%AF%E8%A7%81%E8%BF%99%E6%98%AF%E4%B8%80%E7%A7%8D%E5%85%BC%E5%AE%B9%E5%9E%8B%E6%AF%94%E8%BE%83%E5%A5%BD%E7%9A%84%E5%BD%A2%E6%80%81%E3%80%82%E7%94%9A%E8%87%B3%E5%8F%AF%E4%BB%A5%E5%AF%BC%E5%87%BA%E4%B8%8E%E5%85%B6%E4%BB%96%E8%AF%AD%E8%A8%80%E5%85%B1%E4%BA%AB%E6%AD%A4%E7%B1%BB%E5%8F%98%E9%87%8F%E5%AE%9A%E4%B9%89%E3%80%82%0A%3E%20**C%2B%2B03%E5%AE%9A%E4%B9%89**%0A%3E%20A%20POD-struct%20is%20an%20aggregate%20class%20that%20has%20no%20non-static%20data%20members%20of%20type%20non-POD-struct%2C%20non-POD-union%20(or%20array%20of%20such%20types)%20or%20reference%2C%20and%20has%20no%20user-defined%20copy%20assignment%20operator%20and%20no%20user-defined%20destructor.%20Similarly%2C%20a%20POD-union%20is%20an%20aggregate%20union%20that%20has%20no%20non-static%20data%20members%20of%20type%20non-POD-struct%2C%20non-POD-union%20(or%20array%20of%20such%20types)%20or%20reference%2C%20and%20has%20no%20user-defined%20copy%20assignment%20operator%20and%20no%20user-defined%20destructor.%20A%20POD%20class%20is%20a%20class%20that%20is%20either%20a%20POD-struct%20or%20a%20POD-union.%0A%0A%3E%20C%2B%2B11%E5%AE%9A%E4%B9%89%E5%8F%98%E5%BE%97%E9%9D%9E%E5%B8%B8%E4%BC%98%E9%9B%85%0A%3E%20**A%20POD%20struct%20is%20a%20non-union%20class%20that%20is%20both%20a%20trivial%20class%20and%20a%20standard-layout%20class**%2C%20and%20has%20no%20non-static%20data%20members%20of%20type%20non-POD%20struct%2C%20non-POD%20union%20(or%20array%20of%20such%20types).%20Similarly%2C%20a%20POD%20union%20is%20a%20union%20that%20is%20both%20a%20trivial%20class%20and%20a%20standard%20layout%20class%2C%20and%20has%20no%20non-static%20data%20members%20of%20type%20non-POD%20struct%2C%20non-POD%20union%20(or%20array%20of%20such%20types).%20A%20POD%20class%20is%20a%20class%20that%20is%20either%20a%20POD%20struct%20or%20a%20POD%20union.%0A%0A%E6%80%BB%E8%80%8C%E8%A8%80%E4%B9%8B%EF%BC%9A%0APOD%E7%B1%BB%E5%9E%8B%E6%98%AF%E4%B8%80%E7%A7%8D%E7%89%B9%E6%AE%8A%E7%9A%84%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%EF%BC%8C%E4%B8%80%E4%B8%AAPOD%E7%B1%BB%E5%9E%8B%E4%B8%BA%EF%BC%9A%0A-%20%E6%A0%87%E9%87%8F%E7%B1%BB%E5%9E%8B%E3%80%82%0A-%20%E6%BB%A1%E8%B6%B3%E4%BB%A5%E4%B8%8B%E6%9D%A1%E4%BB%B6%E7%9A%84%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B1%BB%E5%9E%8B%EF%BC%9A%0A%20%20%20%20-%20C%2B%2B11%E4%B9%8B%E5%89%8D%EF%BC%9A%0A%20%20%20%20%20%20%20%20-%20%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%E3%80%82%0A%20%20%20%20%20%20%20%20-%20%E6%B2%A1%E6%9C%89%E9%9D%9EPOD%E7%B1%BB%E5%9E%8B%E7%9A%84%E9%9D%9E%E9%9D%99%E6%80%81%E6%88%90%E5%91%98%E5%8F%98%E9%87%8F%E3%80%82%0A%20%20%20%20%20%20%20%20-%20%E6%B2%A1%E6%9C%89%E5%BC%95%E7%94%A8%E7%B1%BB%E5%9E%8B%E7%9A%84%E9%9D%9E%E9%9D%99%E6%80%81%E6%88%90%E5%91%98%E5%8F%98%E9%87%8F%E3%80%82%0A%20%20%20%20%20%20%20%20-%20%E6%B2%A1%E6%9C%89%E8%87%AA%E5%AE%9A%E4%B9%89%E7%9A%84%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E6%88%96%E6%9E%90%E6%9E%84%E5%87%BD%E6%95%B0%E3%80%82%0A%20%20%20%20-%20C%2B%2B11%E4%B9%8B%E5%90%8E%EF%BC%9A%0A%20%20%20%20%20%20%20%20-%20%E6%98%AF%E5%B9%B3%E5%87%A1%E7%B1%BB%E3%80%82%0A%20%20%20%20%20%20%20%20-%20%E6%98%AF%E6%A0%87%E5%87%86%E5%B8%83%E5%B1%80%E7%B1%BB%E3%80%82%0A%20%20%20%20%20%20%20%20-%20%E6%B2%A1%E6%9C%89%E9%9D%9EPOD%E7%B1%BB%E5%9E%8B%E7%9A%84%E9%9D%9E%E9%9D%99%E6%80%81%E6%88%90%E5%91%98%E5%8F%98%E9%87%8F%E3%80%82%0A-%20POD%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%95%B0%E7%BB%84%E3%80%82%0A%0A%23%20%E8%81%9A%E5%90%88%E7%B1%BB%E5%9E%8B%E6%88%96%E6%98%AFPOD%E5%8F%98%E9%87%8F%E6%9C%89%E4%BB%80%E4%B9%88%E5%A5%BD%E5%A4%84%EF%BC%9F%0A%E8%81%9A%E5%90%88%E7%B1%BB%E6%9C%80%E5%A4%A7%E7%9A%84%E7%89%B9%E7%82%B9%E5%B0%B1%E6%98%AF%E5%8F%AF%E4%BB%A5%E9%87%87%E7%94%A8%E8%81%9A%E5%90%88%E5%88%9D%E5%A7%8B%E5%8C%96%E3%80%82%0APOD%E7%9A%84%E7%89%B9%E7%82%B9%E6%9B%B4%E4%B8%BA%E5%AE%9E%E7%94%A8%E4%B8%80%E4%BA%9B%0A%3E**POD%E7%9A%84%E7%94%A8%E9%80%94**%0A%3E%E5%B9%B3%E5%87%A1%E7%B1%BB%E7%9A%84%E7%94%A8%E9%80%94%EF%BC%9A%0A%3E%0A%3E-%20%E5%B9%B3%E5%87%A1%E7%B1%BB%E7%9A%84%E5%AF%B9%E8%B1%A1%E5%8F%AF%E4%BB%A5%E4%B8%8E%E5%AD%97%E8%8A%82%E6%B5%81%E4%B9%8B%E9%97%B4%E5%AE%89%E5%85%A8%E8%BD%AC%E6%8D%A2%EF%BC%8C%E5%8D%B3%EF%BC%9A%0A%20%20%20%20-%20%E8%8B%A5%E8%A6%81%E5%B0%86%E5%AF%B9%E8%B1%A1%E8%BD%AC%E4%B8%BA%E5%AD%97%E8%8A%82%E6%B5%81%EF%BC%8C%E7%9B%B4%E6%8E%A5%E5%8F%96%E5%85%B6%E5%9C%B0%E5%9D%80%E5%8D%B3%E5%8F%AF%E3%80%82%0A%20%20%20%20-%20%E8%8B%A5%E8%A6%81%E5%B0%86%E5%AD%97%E8%8A%82%E6%B5%81%E8%BD%AC%E4%B8%BA%E5%AF%B9%E8%B1%A1%EF%BC%8C%E7%9B%B4%E6%8E%A5%E5%B0%86%E8%AF%A5%E5%9C%B0%E5%9D%80cast%E4%B8%BA%E5%AF%B9%E8%B1%A1%E6%8C%87%E9%92%88%E5%8D%B3%E5%8F%AF%E3%80%82%0A%20%20%20%20-%20%E7%9B%B4%E6%8E%A5%E9%80%9A%E8%BF%87%E5%A4%8D%E5%88%B6%E5%AD%97%E8%8A%82%E7%9A%84%E6%96%B9%E5%BC%8F%E5%A4%8D%E5%88%B6%E5%AF%B9%E8%B1%A1%E3%80%82%0A%3E-%20%E5%AE%89%E5%85%A8%E7%9A%84%E9%9D%99%E6%80%81%E5%88%9D%E5%A7%8B%E5%8C%96%E3%80%82%0A%20%20%20%20-%20C%2B%2B11%E7%9A%84thread_local%E5%8F%98%E9%87%8F%E5%8F%AF%E4%BB%A5%E6%98%AF%E9%9D%9E%E5%B9%B3%E5%87%A1%E7%B1%BB%E5%9E%8B%EF%BC%8C%E4%BD%86%E5%9C%A8%E6%9F%90%E4%BA%9B%E7%BC%96%E8%AF%91%E5%99%A8%E4%B8%8B%E4%BC%9A%E6%9C%89%E6%AF%94%E8%BE%83%E5%A4%A7%E7%9A%84%E6%80%A7%E8%83%BD%E5%BC%80%E9%94%80%E3%80%82gcc%E6%89%A9%E5%B1%95%E7%9A%84__thread%E5%8F%AA%E8%83%BD%E4%BD%BF%E7%94%A8POD%E7%B1%BB%E5%9E%8B%E3%80%82%0A%3E%0A%3E**%E6%A0%87%E5%87%86%E5%B8%83%E5%B1%80%E7%B1%BB%E7%9A%84%E7%94%A8%E9%80%94%EF%BC%9A**%0A%E8%B7%A8%E8%BF%9B%E7%A8%8B%E3%80%81%E8%B7%A8%E8%AF%AD%E8%A8%80%E4%BD%BF%E7%94%A8%E3%80%82%0A%23%20%E5%90%8D%E6%AC%A1%E8%A7%A3%E9%87%8A%0A%23%23%20value%20initialization%0A-%20%E5%AF%B9%E4%BA%8E%E6%99%AE%E9%80%9A%E7%B1%BB%E5%9E%8B%E5%8F%98%E9%87%8F(bool%2C%20int%2C%20char%2C%20double%2C%20pointers%2C%20etc.)%20%0Ait%20means%20it%20is%20initialized%20with%200%20for%20that%20type%20(false%20for%20bool%2C%200.0%20for%20double%2C%20etc.).%20%0A-%20%E5%AF%B9%E4%BA%8Eclass%E7%B1%BB%E5%9E%8B%0A%20%20%20%20-%20%E5%A6%82%E6%9E%9C%E6%9C%89%E8%87%AA%E5%AE%9A%E4%B9%89%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%EF%BC%8C%E5%88%99%E8%B0%83%E7%94%A8%E8%87%AA%E5%AE%9A%E4%B9%89%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%0A%20%20%20%20-%20%E5%A6%82%E6%9E%9C%E6%B2%A1%E6%9C%89%E8%87%AA%E5%AE%9A%E4%B8%80%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%EF%BC%8C%E5%88%99%E8%B0%83%E7%94%A8%E9%BB%98%E8%AE%A4%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%0A%20%20%20%20-%20%E5%A6%82%E6%9E%9C%E6%B2%A1%E6%9C%89%E5%AF%B9%E5%BA%94%E7%9A%84%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%EF%BC%8C%E5%88%99%E6%8A%A5%E9%94%99%0A%20%20%20%20%0A%E4%B8%BE%E4%BE%8B%0A%60%60%60c%2B%2B%0Aclass%20A%0A%7B%0Apublic%3A%0A%20%20A(int)%20%7B%7D%20%2F%2Fno%20default%20constructor%0A%7D%3B%0Aclass%20B%0A%7B%0Apublic%3A%0A%20%20B()%20%7B%7D%20%2F%2Fdefault%20constructor%20available%0A%7D%3B%0Aint%20main()%0A%7B%0A%20%20A%20a1%5B3%5D%20%3D%20%7BA(2)%2C%20A(1)%2C%20A(14)%7D%3B%20%2F%2FOK%20n%20%3D%3D%20m%0A%20%20A%20a2%5B3%5D%20%3D%20%7BA(2)%7D%3B%20%2F%2FERROR%20A%20has%20no%20default%20constructor.%20Unable%20to%20value-initialize%20a2%5B1%5D%20and%20a2%5B2%5D%0A%20%20B%20b1%5B3%5D%20%3D%20%7BB()%7D%3B%20%2F%2FOK%20b1%5B1%5D%20and%20b1%5B2%5D%20are%20value%20initialized%2C%20in%20this%20case%20with%20the%20default-ctor%0A%20%20int%20Array1%5B1000%5D%20%3D%20%7B0%7D%3B%20%2F%2FAll%20elements%20are%20initialized%20with%200%3B%0A%20%20int%20Array2%5B1000%5D%20%3D%20%7B1%7D%3B%20%2F%2FAttention%3A%20only%20the%20first%20element%20is%201%2C%20the%20rest%20are%200%3B%0A%20%20bool%20Array3%5B1000%5D%20%3D%20%7B%7D%3B%20%2F%2Fthe%20braces%20can%20be%20empty%20too.%20All%20elements%20initialized%20with%20false%0A%20%20int%20Array4%5B1000%5D%3B%20%2F%2Fno%20initializer.%20This%20is%20different%20from%20an%20empty%20%7B%7D%20initializer%20in%20that%0A%20%20%2F%2Fthe%20elements%20in%20this%20case%20are%20not%20value-initialized%2C%20but%20have%20indeterminate%20values%20%0A%20%20%2F%2F(unless%2C%20of%20course%2C%20Array4%20is%20a%20global%20array)%0A%20%20int%20array%5B2%5D%20%3D%20%7B1%2C%202%2C%203%2C%204%7D%3B%20%2F%2FERROR%2C%20too%20many%20initializers%0A%7D%0A%60%60%60%0A%E5%A4%A7%E6%8B%AC%E5%8F%B7%E4%B8%AD%E4%B8%AA%E6%95%B0%E4%B8%8D%E8%B6%B3%E7%9A%84%EF%BC%8C%E7%94%A8value%20initialization%E8%A1%A5%E8%B6%B3%E3%80%82%E8%BF%99%E5%B0%B1%E6%98%AF%60A%20a%20%3D%20%7B1%7D%3B%60%E6%88%96%E8%80%85%60A%20a%20%3D%20%7B%7D%60%E7%9A%84%E5%90%AB%E4%B9%89%E3%80%82%E5%A4%A7%E6%8B%AC%E5%8F%B7%E4%B8%AD%E4%B8%AA%E6%95%B0%E8%B6%85%E8%BF%87%E5%A3%B0%E6%98%8E%E7%9A%84%E4%B8%AA%E6%95%B0%E7%9A%84%EF%BC%8C%E5%88%99%E7%BC%96%E8%AF%91%E6%8A%A5%E9%94%99%E3%80%82%0A%0A%23%23%20brace-or-equal-initializers%0A%E7%B1%BB%E6%88%90%E5%91%98%E7%9A%84%E4%B8%80%E7%A7%8D%E5%88%9D%E5%A7%8B%E5%8C%96%E6%96%B9%E6%B3%95%0A%60%60%60c%2B%2B%0Aclass%20B%20%7B%0Apublic%3A%0A%20%20%20%20B(int)%7B%7D%0A%7D%3B%0A%0Aclass%20A%20%7B%0A%20%20%20%20int%20a%20%3D%20123%3B%0A%20%20%20%20int%20b%20%7B456%7D%3B%0A%20%20%20%20B%20c%20%7B12%7D%3B%0A%20%20%20%20B%20d%20%3D%20%7B34%7D%3B%0A%7D%3B%0A%60%60%60%0A%23%23%20copy-assignment%20operator%0A%E6%8B%B7%E8%B4%9D%E8%B5%8B%E5%80%BC%E6%96%B9%E6%B3%95%0A%60%60%60c%2B%2B%0Aclass%20A%20%7B%0A%20%20%20%20A%20A(int)%20%7B%7D%0A%20%20%20%20A(const%20%26)%20%7B%7D%0A%20%20%20%20A%26%20operator%3D%20(const%20A%26a)%20%7B%7D%0A%7D%3B%0Avoid%20main()%20%7B%0A%20%20%20%20A%20a%3B%0A%20%20%20%20A%20b%20%3D%20a%3B%20%2F%2F%20%E8%BF%99%E9%87%8C%E8%B0%83%E7%94%A8%E7%9A%84%E6%98%AF%E6%8B%B7%E8%B4%9D%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%0A%20%20%20%20A%20c%3B%0A%20%20%20%20c%20%3D%20a%3B%20%2F%2F%20%E8%BF%99%E9%87%8C%E6%89%8D%E4%BC%9A%E8%B0%83%E7%94%A8%E6%8B%B7%E8%B4%9D%E5%A4%8D%E5%88%B6%E5%87%BD%E6%95%B0%0A%7D%0A%60%60%60%0A%23%23%20trial%20stuff%0A%23%23%23%20trivial%20copyable%0A%E5%8F%82%E8%80%83%5BC%2B%2B%20named%20requirements%3A%20TriviallyCopyable%5D(https%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Fnamed_req%2FTriviallyCopyable)%0A%3E%20The%20following%20types%20are%20collectively%20called%20trivially%20copyable%20types%3A%0A%3E%20-%20Scalar%20types%0A%3E%20-%20Trivially%20copyable%20classes%2C%20i.e.%20classes%20satisfying%20following%20requirements%3A%0A%20%20%20%20-%20At%20least%20one%20copy%20constructor%2C%20move%20constructor%2C%20copy%20assignment%20operator%2C%20or%20move%20assignment%20operator%20is%20eligible%0A%20%20%20%20-%20Every%20eligible%20copy%20constructor%20(if%20any)%20is%20trivial%0A%20%20%20%20-%20Every%20eligible%20move%20constructor%20(if%20any)%20is%20trivial%0A%20%20%20%20-%20Every%20eligible%20copy%20assignment%20operator%20(if%20any)%20is%20trivial%0A%20%20%20%20-%20Every%20eligible%20move%20assignment%20operator%20(if%20any)%20is%20trivial%0A%20%20%20%20-%20Has%20a%20trivial%20non-deleted%20destructor%0A%3E%20-%20Arrays%20of%20TriviallyCopyable%20objects%0A%3E%0A%3E%20This%20implies%20that%20a%20trivially%20copyable%20class%20has%20no%20virtual%20functions%20or%20virtual%20base%20classes.%0A%0A%E9%80%9A%E8%BF%87%E6%A8%A1%E7%89%88%5Bstd%3A%3Ais_trivially_copyable%5D(https%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Ftypes%2Fis_trivially_copyable)%E5%8F%AF%E4%BB%A5%E6%A3%80%E9%AA%8C%E4%B8%80%E4%B8%AA%E7%B1%BB%E6%98%AF%E5%90%A6trivially%20copyable%E3%80%82%0A%23%23%23%20trivial%20constructor%2Fdestructor%0A-%20%E7%BC%96%E8%AF%91%E5%99%A8%E5%AE%9A%E4%B9%89%E7%9A%84%E6%9E%84%E9%80%A0%2F%E6%9E%90%E6%9E%84%E5%87%BD%E6%95%B0%0A-%20%E7%94%A8%60%3Ddefault%60%E5%AE%9A%E4%B9%89%E7%9A%84%E6%9E%84%E9%80%A0%E6%9E%90%E6%9E%84%E5%87%BD%E6%95%B0%0A%23%23%23%20trivial%20class%0AThe%20standard%20defines%20a%20trivial%20class%20as%20follows%3A%0A%0AA%20trivially%20copyable%20class%20is%20a%20class%20that%3A%0A%0A-%20has%20no%20non-trivial%20copy%20constructors%20(12.8)%2C%0A-%20has%20no%20non-trivial%20move%20constructors%20(12.8)%2C%0A-%20has%20no%20non-trivial%20copy%20assignment%20operators%20(13.5.3%2C%2012.8)%2C%0A-%20has%20no%20non-trivial%20move%20assignment%20operators%20(13.5.3%2C%2012.8)%2C%20and%0A-%20has%20a%20trivial%20destructor%20(12.4).%0A%0AA%20trivial%20class%20is%20a%20class%20that%20has%20a%20trivial%20default%20constructor%20(12.1)%20and%20is%20trivially%20copyable.%0A%0A%5B%20Note%3A%20In%20particular%2C%20a%20trivially%20copyable%20or%20trivial%20class%20does%20not%20have%20virtual%20functions%20or%20virtual%20base%20classes.%20%5D%0A%E5%8F%A6%E5%A4%96trivial%20class%E6%98%AF%E9%80%92%E5%BD%92%E7%9A%84%EF%BC%8C%E5%8D%B3trivial%20class%E4%B8%8D%E8%83%BD%E6%9C%89%E9%9D%9Etrivial%20class%E7%9A%84%E9%9D%9Estatic%E6%88%90%E5%91%98%E3%80%82%0A%E7%94%A8%E6%A8%A1%E7%89%88%5Bstd%3A%3Ais_trivial%5D(https%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Ftypes%2Fis_trivial)%E6%9D%A5%E6%B5%8B%E8%AF%95%0A%23%23%20standard%20layout%0AA%20standard-layout%20class%20is%20a%20class%20that%3A%0A%0A-%20has%20no%20non-static%20data%20members%20of%20type%20non-standard-layout%20class%20(or%20array%20of%20such%20types)%20or%20reference%2C%0A%0A-%20has%20no%20virtual%20functions%20(10.3)%20and%20no%20virtual%20base%20classes%20(10.1)%2C%0A%0A-%20has%20the%20same%20access%20control%20(Clause%2011)%20for%20all%20non-static%20data%20members%2C%0A%0A-%20has%20no%20non-standard-layout%20base%20classes%2C%0A%0A-%20either%20has%20no%20non-static%20data%20members%20in%20the%20most%20derived%20class%20and%20at%20most%20one%20base%20class%20with%20non-static%20data%20members%2C%20or%20has%20no%20base%20classes%20with%20non-static%20data%20members%2C%20(%E8%A6%81%E4%B9%88%E7%BB%88%E7%82%B9%E7%B1%BB%E6%B2%A1%E6%9C%89%E9%9D%9E%E9%9D%99%E6%80%81%E6%88%90%E5%91%98%EF%BC%8C%E5%B9%B6%E4%B8%94%E5%8F%AA%E6%9C%89%E4%B8%80%E4%B8%AA%E5%9F%BA%E7%B1%BB%E6%9C%89%E9%9D%9E%E9%9D%99%E6%80%81%E6%88%90%E5%91%98%EF%BC%9B%E8%A6%81%E4%B9%88%E6%B2%A1%E6%9C%89%E5%9F%BA%E7%B1%BB%E6%9C%89%E9%9D%9E%E9%9D%99%E6%80%81%E6%88%90%E5%91%98)%EF%BC%8Cand%0A%0A-%20has%20no%20base%20classes%20of%20the%20same%20type%20as%20the%20first%20non-static%20data%20member.%0A%0AA%20standard-layout%20struct%20is%20a%20standard-layout%20class%20defined%20with%20the%20class-key%20struct%20or%20the%20class-key%20class.%0A%0AA%20standard-layout%20union%20is%20a%20standard-layout%20class%20defined%20with%20the%20class-key%20union.%0A%0A%5B%20Note%3A%20Standard-layout%20classes%20are%20useful%20for%20communicating%20with%20code%20written%20in%20other%20programming%20languages.%20Their%20layout%20is%20specified%20in%209.2.%5D%0A%0A%E6%A0%87%E5%87%86%E5%86%85%E5%AD%98%E5%88%86%E5%B8%83%EF%BC%8C%E7%A1%AE%E4%BF%9D%E5%AF%B9%E8%B1%A1%E5%86%85%E5%AD%98%E5%92%8CC%E8%AF%AD%E8%A8%80%E7%9A%84%E7%BB%93%E6%9E%84%E4%BD%93%E5%86%85%E5%AD%98%E5%88%86%E5%B8%83%E5%AE%8C%E5%85%A8%E4%B8%80%E8%87%B4%E3%80%82%E4%BD%BF%E5%BE%97POD%E5%8F%98%E9%87%8F%E5%85%B7%E5%A4%87%E4%BA%86C%E5%85%BC%E5%AE%B9%E6%80%A7%E3%80%82%0A%E7%94%A8%E6%A8%A1%E7%89%88%5Bstd%3A%3Ais_standard_layout%5D(https%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Ftypes%2Fis_standard_layout)%E5%8F%AF%E4%BB%A5%E6%B5%8B%E8%AF%95%0A%0A%23%20%E6%80%BB%E7%BB%93%0A%E7%94%A8%5Bstd%3A%3Ais_pod%5D(https%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Ftypes%2Fis_pod)%E6%9D%A5%E6%B5%8B%E8%AF%95%E4%BD%A0%E7%9A%84%E7%B1%BB%E5%90%A7%E3%80%82%0A%23%20%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE%0A1.%20%5BWhat%20are%20Aggregates%20and%20PODs%20and%20how%2Fwhy%20are%20they%20special%3F%5D(https%3A%2F%2Fstackoverflow.com%2Fquestions%2F4178175%2Fwhat-are-aggregates-and-pods-and-how-why-are-they-special)%0A2.%20%5BC%2B%2B%E5%AF%B9%E8%B1%A1%E6%A8%A1%E5%9E%8B%EF%BC%88%E4%B8%89%EF%BC%89POD%5D(https%3A%2F%2Ffuzhe1989.github.io%2F2018%2F03%2F15%2Fcpp-object-model-pod%2F)