POD

2018-07-11  本文已影响0人  混世太保

POD是英文中Plain Old Data的缩写。
Plianb表示了POD是个普通类型。
Old则体现了其与C的兼容性。比如可以用最老的memcpy函数进行复制,可以用memset进行初始化等。

c++11将POD划分成两个基本概念的合集。即平凡的(trivial)和标识布局的(standard layout)
那么什么是平凡的。
1.拥有平凡的默认构造函数(trivial constructor)和析构函数(trivial destructor)
2.拥有平凡的拷贝构造函数(trivial constructor)和移动构造函数(trivial move constructor).
3.拥有平凡的拷贝赋值运算符(trivial assignment operator)和移动赋值运算符(trivial move operator)
4.不能包含虚函数以及虚基类。
平凡的(trivial)意味着该方式你就不要去实现了。你就放着让编译器默认去实现就好了。只要你一旦定义了方法,那么它就是non-trivial(非平凡化)
c++11也提供了辅助的类模板来帮助你进行判断了。

template <typename T>
struct std::is_trivial;

具体实现方式是

include<type_traits>

std::is_trivial<T>::value

1是trivial
0是non-trivial

标准布局。
1.所有非静态成员有相同的访问权限
2.在类或者结构体继承时,满足以下两种情况之一:
派生类中有非静态成员,且只有一个仅包含静态成员的基类。
基类有非静态成员,而派生类没有非静态成员。
意思就是只要派生类和基类同时出现非静态成员,则不属于标准布局。
非静态成员出现在多个基类中,则也不属于标准布局。
3.类中的第一个非静态成员的类型与基类不同。
这个规则的产生是c++中允许优化不包含成员的基类而产生的。
因为在c++标准中,如果基类没有成员,标准允许派生类的第一个成员与基类共享地址。
但是如果派生类的第一个成员和基类一致,编译器会为基类分配一字节空间。这是由于c++标准要求类型相同的对象必须地址不同。而导致的。
4.没有虚函数和虚基类。
5.所有非静态成员均符合标准布局类型,其基类也符合标准布局类型。

同样,我们也可以用模板类来判断类型是否是一个标准布局的类型。
template<typename T> struct std::is_standard_layout;

我们也可以用模板类来判断类型是否是POD。都在标准库的头文件<type_traits>
template<typename T> struct std::is_pod;

都是有一个成员变量value。

使用POD有什么好处呢?
1.字节赋值。可以安全地用memcpy和memset对POD的类型进行初始化。
2.提供了对c内存布局兼容。c++程序可以与c函数进行互相操作,因为POD类型的数据在c与c++间的操作总是安全的。
3.保证静态初始化的安全有效。

上一篇下一篇

猜你喜欢

热点阅读