什么是POD类型
POD的全称叫做Plain Old Data,简单讲就是一个类或者一个结构体通过二进制拷贝之后还能保持其不变,那么这个类型就是POD类型。
什么类型属于POD类型
当一个类型具有平凡的定义和标准布局这两种情况时,才可以说这种类型是POD类型。
什么是平凡的定义的类型
当一个类具有以下的几个定义时,才可以说是平凡的类:
代码示例
#include <iostream>
using namespace std;
class A { A(){} };
class B { B(B&){} };
class C { C(C&&){} };
class D { D operator=(D&){} };
class E { E operator=(E&&){} };
class F { ~F(){} };
class G { virtual void foo() = 0; };
class H : G {};
class I {};
int main(int argc, _TCHAR* argv[])
{
std::cout << std::is_trivial<A>::value << std::endl;
std::cout << std::is_trivial<B>::value << std::endl;
std::cout << std::is_trivial<C>::value << std::endl;
std::cout << std::is_trivial<D>::value << std::endl;
std::cout << std::is_trivial<E>::value << std::endl;
std::cout << std::is_trivial<F>::value << std::endl;
std::cout << std::is_trivial<G>::value << std::endl;
std::cout << std::is_trivial<H>::value << std::endl;
std::cout << std::is_trivial<I>::value << std::endl;
system("pause");
return 0;
}
什么是标准布局的类型
- 所有非静态成员具有相同的访问权限
- 在继承树中最多只有一个类中有非静态数据成员
- 子类中的第一个非静态成员的类型与其基类不同
因为如果相同,C++会为基类分配1字节的空间,因为C++中规定相同类型的对象必须拥有不同的地址 - 没有虚函数和虚基类
- 所有非静态数据成员均符合标准布局类型,其基类也符合标准布局
代码示例
#include <iostream>
using namespace std;
class A
{
private:
int a;
public:
int b;
};
class B1
{
static int x1;
};
class B2
{
int x2;
};
class B : B1, B2
{
int x;
};
class C1 {};
class C : C1
{
C1 c;
};
class D { virtual void foo() = 0; };
class E : D {};
class F { A x; };
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << std::is_standard_layout<A>::value << std::endl;
std::cout << std::is_standard_layout<B>::value << std::endl;
std::cout << std::is_standard_layout<C>::value << std::endl;
std::cout << std::is_standard_layout<D>::value << std::endl;
std::cout << std::is_standard_layout<E>::value << std::endl;
std::cout << std::is_standard_layout<F>::value << std::endl;
system("pause");
return 0;
}
POD类型的使用方法
下面一个一个复制POD类型为例的代码
#include <iostream>
#include <Windows.h>
using namespace std;
class A
{
public:
int x;
double y;
};
int _tmain(int argc, _TCHAR* argv[])
{
if (std::is_pod<A>::value)
{
std::cout << "before" << std::endl;
A a;
a.x = 8;
a.y = 10.5;
std::cout << a.x << std::endl;
std::cout << a.y << std::endl;
size_t size = sizeof(a);
char *p = new char[size];
memcpy(p, &a, size);
A *pA = (A*)p;
std::cout << "after" << std::endl;
std::cout << pA->x << std::endl;
std::cout << pA->y << std::endl;
delete p;
}
system("pause");
return 0;
}
POD类型的好处
- 字节赋值。这样就可以使用C语言中的memset和memcpy对POD类型进行初始化
- 提供C对的内存布局的兼容。因为POD类型的数据在C和C++间的操作都是安全的
- 保证静态初始化的安全。静态初始化可以提高性能,POD类型对象的初始化更加简单
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)