POD,全称plain old data,plain代表它是一个普通类型,old代表它可以与c兼容,可以使用比如memcpy()这类c中最原始函数进行操作。C++11中把POD分为了两个基本概念的集合,即:平凡的(trival)和标准布局的(standard layout)。

1、首先是平凡的(trival)定义,通常一个平凡的类或者结构体需要满足以下定义

  (1).拥有平凡的默认构造函数和析构函数。默认的意思就是由编译器为我们自动生成的,不许是我们自己定义的,而一旦定义了构造函数,即使函数体里没有任何代码,那么该构造函数也不在是平凡的,但是由于c++11提供了default,也可以是自己定义的加=default。

  (2).拥有平凡的拷贝构造函数和移动构造函数。默认的意思同上,也可以使用=default。

  (3).拥有平凡的拷贝赋值运算符和移动赋值运算符。

  (4).不能包含虚函数和虚基类。

C++11中,我们使用模版类std::is_trivial<T>::value来判断数据类型是否为平凡类型。

#include "stdafx.h"
#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 _tmain(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;  //平凡的类return 0;
}

2.接下来是标准布局的定义

(1).所有非静态成员拥有相同的访问级别,(访问级别就是public,private,protected)

struct t1{
private :int a;
public:int b;
};       //不满足标准布局,因为a,b访问级别不同。

(2).在类和结构体继承时需要满足以下两个情况之一:

  派生类中有非静态类,那么这个派生类只能有且只有一个仅包含了静态成员的基类。

  基类有非静态成员,那么派生类中不允许有非静态成员。

(这两句话看着挺绕口,其实就是在说明一个事实,关于非静态数据的事实,派生类中有非静态的数据那么它的基类只能是只有静态的,而且基类只能有一个。如果基类有非静态的, 那么派生类就不能有非静态的。有种跷跷板的感觉,非静态的对面坐着的是静态,父子类就 是坐在跷跷板的两端这种对应关系。)

(3).类中第一个非静态类型与基类不是同一个类型。比如

struct A:B{B b;int c;
}    //不符合这个条件。因为A中第一个成员是基类B类型的

(4).没有虚类和虚基类(与trival中重复)

(5).所有非静态数据成员都符合标准布局的要求,这其实就是一个递归的定义。

C++11中,我们使用模版类std::is_standard_layout<A>::value来判断类型是否是一个标准布局类型。

所以在C++11中,POD就是满足平凡的(trival)和标准布局(standard layout)这两个方面。

可以使用<type_traits>中的is_pod<T>::value判断T是不是POD类型的。

#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 main()
{std::cout << std::is_standard_layout<A>::value << std::endl;  //违反定义1,成员a和b具有不同的访问权限std::cout << std::is_standard_layout<B>::value << std::endl;  //违反定义2,继承树有两个(含)以上的类有非静态成员std::cout << std::is_standard_layout<C>::value << std::endl;  //违反定义3,第一个非静态成员是基类类型std::cout << std::is_standard_layout<D>::value << std::endl;  //违反定义4,有虚函数std::cout << std::is_standard_layout<E>::value << std::endl;  //违反定义5,有虚基类std::cout << std::is_standard_layout<F>::value << std::endl;  //违反定义6,非静态成员x不符合标准布局类型return 0;
}

View Code

#include <iostream>
#include <cstring>using namespace std;class AA
{
public:int x;double y;
};int main()
{if (std::is_pod<AA>::value) {cout << "before" << endl;AA aa;aa.x = 10;aa.y = 20.0f;cout << aa.x << " " << aa.y << endl;size_t size = sizeof(aa);char *p = new char[size];memcpy(p, &aa, size);AA *pA = (AA*)p;cout << "after" << endl;cout << pA->x << " " << pA->y << endl;delete p;}return 0;
}

View Code

说了这么多,那么为什么我们需要POD这种条件满足的数据呢?

  (1).可以使用字节赋值,比如memset,memcpy操作

  (2).对C内存布局兼容。

  (3).保证了静态初始化的安全有效。

C++11 POD类型相关推荐

  1. C++11 POD 类型

    POD(Plain Old Data,普通旧数据)类型是从 C++11 开始引入的概念,Plain 代表一个对象是一个普通类型,Old 代表一个对象可以与 C 兼容.通俗地讲,一个类.结构.共用体对象 ...

  2. C++11新特性之POD类型

    POD(Plain Old Data)是C++中非常重要的一个概念,用来描述一个类型的属性其中Plain表示这个类型是个平凡的类型,Old表示其与C的兼容性.C++11中将POD划分为两个基本概念:平 ...

  3. C++11的POD类型

    POD类型的定义 必须是平凡的和有标准布局的. 平凡的构造函数与析构函数是默认的,不起任何作用的.如果自定义了,那么需要声明为default类型的. 使用std::is_trivial进行判别. 标准 ...

  4. C ++中的POD类型是什么?

    我有几次遇到这个术语POD型. 这是什么意思? #1楼 POD代表普通旧数据 - 即没有构造函数,析构函数和虚拟成员函数的类(无论是使用关键字struct还是关键字class ). 维基百科关于POD ...

  5. C++中的trivial和non-trivial构造/析构/拷贝/赋值函数及POD类型

    在侯捷的<STL源码剖析>里提到trivial和non-trivial及POD类型,相关知识整理如下. trivial意思是无意义,这个trivial和non-trivial是对类的四种函 ...

  6. 【C/C++ POD 类型】深度解析C++中的POD类型:从理论基础到项目实践

    深度解析C++中的POD类型:从理论基础到项目实践 1. C++中的POD类型(Plain Old Data) 1.1 POD类型的定义和特性 Trivial类型 Standard layout类型 ...

  7. C/C++编程:POD类型

    概叙 很久之前,C语言统一了江湖,几乎所有的系统底层都是用C写的,当时定义大的基本数据类型类型有 int.char.float 等整数类型.浮点类型.枚举.void.指针.数组.结构等等.然后只要碰到 ...

  8. C++ trivial和non-trivial构造函数及POD类型(转)

    原博客地址http://blog.csdn.net/a627088424/article/details/48595525 最近正纠结这个问题就转过来了,做了点补充(参考<深度探索C++对象模型 ...

  9. c++中的pod类型

    最早看到POD(plain old data)类型,是在imperfect c++里.我觉得这是一本把我带到c++世界里的一本很重要的书. 书里是这样解释POD的: 1.   所有标量类型(基本类型和 ...

最新文章

  1. Windows Server中的故障转移群集的实现机制
  2. angular微信支付实际url地址不同
  3. C语言 递归求阶乘和
  4. Sklearn 损失函数如何应用到_Sklearn全复习(下)(持续更新)
  5. how to query for a listString in jdbctemplate?--转载
  6. 网络资产管理系统_固定资产管理系统网络版的各种语言翻译
  7. 可视化大作业复习笔记
  8. InletexEMC 多人屏幕共享工具
  9. UG(NX)二次开发 BlockUI 集列表使用方法
  10. Silverlight/Windows8/WPF/WP7/HTML5周学习导读(9月10日-9月16日)
  11. JavaWeb项目上云教程(Java项目在腾讯云上部署操作教程)
  12. 浅谈股价预测模型:分类树算法
  13. 大写金额换算器iOS版源代码
  14. springboot easyexcel导出百万数据优化
  15. 刷机需要的常识双清,BL,REC,TWRP,ROM
  16. PHP7.2源码安装
  17. 基于单片机的智能洗手器系统设计(#0460)
  18. Xilinx ZYNQ SOC入门基础之使用SDK自带程序测试内存及DRAM实验
  19. STM8L101活跃停机(AWU)编程教学
  20. matlab求解常微分方程,matlab 求解常微分方程式

热门文章

  1. GDCM:处理(各种操作处理)DICOM图像文件的测试程序
  2. Boost::context模块fiber的jump测试程序
  3. Boost::context模块fiber的回声测试程序
  4. VTK:PolyData之Outline
  5. VTK:图片之Cast
  6. c++STL容器的Vector
  7. linux虚拟网桥配置nat,使用NAT在Proxmox VE 6上创建专用网桥的方法
  8. dvi黑屏解决方法_赛博朋克2077黑梦黑屏怎么办 黑梦BUG全黑模式解决方法
  9. matlab将字符矩阵,matlab – 将字符串索引输入矩阵
  10. c++ 获取linux系统信息_linux系统c程序移植