C++ POD类型
背景
POD(Plain Old Data)指的是C++定义的和C相兼容的数据结构。
几乎所有的系统底层都是用C写的,当时定义的基本数据类型比如int、char、float、枚举、指针、数组和结构等通过二进制拷贝后还能保持数据不变,即编译器可以通过二进制数据将该类型正确解析出来。C++中的类类型引入了继承和派生等新概念,编译器无法解析这些复杂数据结构,因此C++提出POD数据结构的概念用于兼容C语言,由于C++中基本内置类型都是POD类型,因此我们一般讨论class
、struct
和union
是否是POD类型的。
POD类型的优势
1. C内存布局兼容
POD类型兼容C内存布局,C++可以直接使用C库函数操作POD数据类型,POD类型在C和C++间的操作总是安全的。
2. 可以使用字节赋值
POD类型可以直接使用字节赋值,使用C语言库函数进行二进制形式的数据交换,包括但不限于如下操作:
malloc
创建memset
设置内存memcpy
和memmove
拷贝内存
3. 保证静态初始化的安全有效
静态初始化在很多时候可以提高程序性能,而POD类型的静态初始化非常简单(放入目标文件的.bss
段,在初始化时直接赋0)
4. 其他特性
虽然与C完全兼容,但是仍然可以有成员函数
有更长的生命周期(从资源获取到资源释放),非POD类型的生命周期从构造函数结束到析构函数结束
POD类型对象的前部没有填充字节,因此对象指针等于对象第一个成员的指针
POD类型判断
在C++中,可以通过
is_pod<T>::value
来判断某个类型是否是POD类型。
POD类型的具体要求如下(这里只讨论类类型,即class
、struct
和union
):
1. trival
一个类类型是trival
的需要满足如下条件:
默认指的是编译器自动生成的版本,用户定义的拷贝控制操作即使函数体为空也不算
trival
的,C++11以后可以使用=default
显式使用编译器自动生成的版本。
默认的构造函数与析构函数
默认的拷贝构造函数和移动构造函数
默认的拷贝赋值运算符和移动赋值运算符
不能包含虚函数和虚基类
2. 标准布局
所有非静态数据均为标准布局类型
所有基类均为标准布局类型
所有非静态成员具有相同的访问权限
没有虚函数
没有虚基类
类中的第一个非静态成员与其任何基类的类型不同
要么所有基类都没有非静态成员,要么最下层的子类没有非静态成员且最多只有基类有非静态数据成员(总之继承树中最多只能有一个类有非静态数据成员)
Reference
[1] https://zhuanlan.zhihu.com/p/45545035
[2] https://blog.csdn.net/kongkongkkk/article/details/77414410
[3] https://www.cnblogs.com/jerry-fuyi/archive/2020/05/09/12854248.html