[C++11阅读][2-3-3]POD类型(上)

POD是Plain Old Data的缩写。POD类型是C++11中其他概念的基础,在后续会看到各处的应用。
Plain指的是每个类都有这样的属性,Old指的是与C的兼容,比如用memcpy()、memset()进行赋值。
C++11将POD划分成两个基本概念的合集:平凡的(trivial)和标准布局的(standard layout)。
两个条件是缺一不可的。

trivial

一个平凡的类或结构体应当符合以下条件:

  1. 拥有平凡的默认构造函数和默认析构函数
    当自定义了构造/析构函数时,默认函数会被删掉,哪怕自定义的构造/析构函数啥也没干,也会不符合trivial。
    有个技巧是可以通过=default关键帧恢复trivial。
  2. 拥有平凡的拷贝构造函数和移动构造函数
  3. 拥有平凡的拷贝赋值运算符和移动赋值运算符
  4. 不能包含虚函数以及虚基类
    我们看几个示例。
#include 
#include 
using namespace std;
struct Trivial1 {};
struct Trivial2 {
public:
    int a;
private:
    int b;  // 同时有public和private符合trivial,但不符合standard layout
};
struct Trivial3 {
    Trivial1 a;
    Trivial2 b;
};
struct Trivial4 {
    Trivial2 a[23];
};
struct Trivial5 {
    int x;
    static int y;  // 同时也是standard layout和pod
};
struct NonTrivial1 {
    NonTrivial1(): z(42) {}
    int z;
};
struct NonTrivial2 {
    NonTrivial2();
    int w;
};
NonTrivial2::NonTrivial2() = default;  // 实测这样写无法恢复,但写在里面是可以的
struct NonTrivial3 {
    Trivial5 c;
    virtual void f();
};
int main() {
    cout << is_trivial::value << endl;
    cout << is_trivial::value << endl;
    cout << is_standard_layout::value << endl;  // 0
    cout << is_pod::value << endl;  // 0
    cout << is_trivial::value << endl;
    cout << is_trivial::value << endl;
    cout << is_trivial::value << endl;
    cout << is_standard_layout::value << endl;  // 1
    cout << is_pod::value << endl;  // 1
    cout << is_trivial::value << endl;
    cout << is_trivial::value << endl;
    cout << is_trivial::value << endl;
}

你可能感兴趣的:([C++11阅读][2-3-3]POD类型(上))