POD 是英文中Plain Old Data 的缩写,意如其名。 Plain 表示了POD 是普通的类型, C++中常见的类型都是这样的属性,而不像一些存在着虚函数虚继承的类型那么特别。 Old 则体现其和C 的兼容性。 比如可以用古老的memcpy() 函数进行复制, 使用memset()进行初始化等。

使用POD 有以下几个好处:

1. 字节赋值, 可以安全地使用memset 和memcpy对POD 进行初始化和拷贝等操作。

2. 提供对C内存布局兼容,C++ 程序可以与C函数进行相互操作,因为POD 的类型的数据在C和C++间操作总是安全的

3. 保证了静态初始化的安全有效。 静态初始化在很多时候能够提升程序的性能,而POD 类型的对象初始化往往简单(比如放在目标文件的.bss 段,在初始化中直接赋0)。

在C++ 11 中,对POD 划分为两个概念的集合, 即: 平凡的(Trivial) 和标准布局的。

  通常情况下, 一个平凡的类或结构体应该符合以下定义

  1. 拥有平凡的默认构造函数(Trivial constructor)和析构函数(trivial destructor)

    平凡的默认构造函数就是说构造函数什么都不干, 通常情况下, 不定义类的构造函数,编译器会为我们生产一个平凡的默认构造函数,而一旦定义了构造函数,即使构造函数不包含参数,函数提里面没有任何代码,那么该构造函数也就不再是 ‘平凡的‘。 比如:

struct NonTrivial
{Nontrivial() {}
};

 也可以使用=default关键字显式申明缺省的版本的构造函数,使其’平凡化‘。

  2. 拥有平凡 的拷贝构造函数(trivial copy constructor)和移动构造函数(trivial move constructor). 平凡的拷贝构造函数基本上等同于使用memcpy进行类型的构造。同样地,也可使用=default申明默认的拷贝构造函数。平凡的移动构造函数和平凡的拷贝构造函数类似,只不是用于移动语义。

  3. 拥有平凡的拷贝赋值运算符(trivial assignment operator) 和移动赋值运算符(Trivial move operator),基本上与平凡的拷贝构造函数和平凡的移动构造函数运算符类似。

  4. 不能包含虚函数和虚继承

在C++ 11 中,可以使用辅助类模版类判断一个类或结构体是不是平凡的

template <typename T> struct std::is_trivial;

类is_trivial 的成员value 可以用于判断类型T 是不是平凡的类型。下面的代码总结了这四种情况:

#include <iostream>
#include <type_traits>using namespace std;struct Trivial1 { };
struct Trivial2 {
public: int a;
private:int b;
};struct Trivial3{Trivial1 a;Trivial2 b;
};struct Trivial4{Trivial2 a[20];
};struct Trivial5{int x;static int y;
};struct NonTrivial1{NonTrivial1() : z(42){}int z;
};struct NonTrivial2{NonTrivial2(){}int w;};struct NonTrivial3
{Trivial5 c;virtual void f(){}
};int main(int argc, char* argv[])
{cout << is_trivial<Trivial1>::value << endl; //1cout << is_trivial<Trivial2>::value << endl; //1cout << is_trivial<Trivial3>::value << endl; //1cout << is_trivial<Trivial4>::value << endl; //1cout << is_trivial<Trivial5>::value << endl; //1cout << is_trivial<NonTrivial1>::value << endl; //0cout << is_trivial<NonTrivial2>::value << endl; //0cout << is_trivial<NonTrivial3>::value << endl; //0return 0;
}

POD 包含的另外一个概念是标准布局, 标准布局的类或结构体应该符合以下的定义:

  1. 所有非静态成员有相同的访问权限(Public, protected, private)

  2. 在类或结构体继承时,满足一下两种情况之一

    a. 派生类中有非静态成员,且只有一个仅包含静态成员的基类

    b. 基类有非静态成员,而派生类没有非静态成员

  这样的类或结构体是标准布局的,比如下面的例子:

  

struct B1 { static int a; } ;
struct D1 : B1 { int d; };struct B2 { int a; };
struct D2 : B2 { static int d; };struct D3 : B2, B1 { static int d; };
struct D4 : B2 { int d; };
struct D5: B2, D1 { };

  D1, D2, D3都是标准布局的, D4,D5则不属于标准布局,这实际上使得非静态成员只要同时出现在基类或者派生类中, 其即属于非标准布局,而多重继承也会导致类型布局的一些变化,所以一旦非静态成员出现在多个基类中,派生类也不属于标准布局

  3. 类中的第一个非静态成员的类型与其基类相同

  

struct A : B { B b; };

  这样的情况A 就不是一个标准布局,而如下例子:

struct A:B {int a; B b; };

则是一个标准布局

  

  4. 没有虚函数和虚继承

  5. 所有非静态数据成员均符合标准布局类型,其基类也符合标准布局。

同样,在C++11 中,可以使用模版类is_standard_layout 来判断一个类是不是标准布局的

template <typename T> struct std::is_standard_layout

通过is_standard_layout 模版类的成员 value, 可以判断出其实不是标准布局。

#include <iostream>
#include <type_traits>
using namespace std;
struct SLayout1
{};
struct SLayout2
{
private:int a;int b;
};struct SLayout3 : SLayout1
{int a;int b;void f(){}
};struct SLayout4 : SLayout1
{int a;SLayout1 b;
};struct SLayout5 : SLayout1, SLayout3 { };struct SLayout6 { static int a; };struct SLayout7 :SLayout6 { int a; };struct NonSLayout1 : SLayout1{ SLayout1 a; int i; };
struct NonSLayout2 : SLayout2{ int c; };
struct NonSLayout3 : NonSLayout2 {};
struct NonSLayout4
{
public: int a;
private:int b;
};int main(int argc, char* argv[])
{cout << "Is Standard layout:" << endl;cout << is_standard_layout<SLayout1>::value << endl; //1cout << is_standard_layout<SLayout2>::value << endl; //1cout << is_standard_layout<SLayout3>::value << endl; //1cout << is_standard_layout<SLayout4>::value << endl; //1cout << is_standard_layout<SLayout5>::value << endl; //1cout << is_standard_layout<SLayout6>::value << endl; //1cout << is_standard_layout<SLayout7>::value << endl; //1cout << is_standard_layout<NonSLayout1>::value << endl; //0cout << is_standard_layout<NonSLayout2>::value << endl; //0cout << is_standard_layout<NonSLayout3>::value << endl; //0return 0;
}

同样,要判断一个类型是不是POD, 标准库中的<type_traits> 头文件提供了如下模版类:

template<typename T> struct std::is_pod;

可以使用std::is_pod<T>::value 来判断一个类型是不是POD。

转载于:https://www.cnblogs.com/zhouminliang/p/3357073.html

C++ 11 中的POD相关推荐

  1. C++11中的POD和Trivial

    引子 在介绍C++11的文章或者博客中,经常会出现POD类型和Trivial类型的影子.但是POD类型和Trivial类型到底是什么意思呢? POD类型 POD类型的好处 POD类型 粗略上来讲,PO ...

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

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

  3. C++11中头文件type_traits介绍

    C++11中的头文件type_traits定义了一系列模板类,在编译期获得某一参数.某一变量.某一个类等等类型信息,主要做静态检查. 此头文件包含三部分: (1).Helper类:帮助创建编译时常量的 ...

  4. C++11中值得关注的几大变化 .

    Lambda 表达式 Lambda 表达式的形式是这样的: view plaincopy to clipboardprint? [capture](parameters)->return-typ ...

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

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

  6. C++11中值得关注的几大变化

    赖勇浩(http://laiyonghao.com) 声明:本文源自 Danny Kalev 在 2011 年 6 月 21 日发表的<The Biggest Changes in C++11( ...

  7. C++11 中值得关注的几大变化

    2019独角兽企业重金招聘Python工程师标准>>> 源文章来自前C++标准委员会的 Danny Kalev 的 The Biggest Changes in C++11 (and ...

  8. C++11中的右值引用(对比左值引用和常引用)、移动构造函数和引用标识符

    Hello!各位同学们大家好!逗比老师最近说起来还是挺尴尬的,为什么这么说呢?因为以前我对自己的C++水平还是相当自信的,经常以"精通"来自我评价.但是最近发现自己好像对C++11 ...

  9. C++11中std::async的使用

    C++11中的std::async是个模板函数.std::async异步调用函数,在某个时候以Args作为参数(可变长参数)调用Fn,无需等待Fn执行完成就可返回,返回结果是个std::future对 ...

最新文章

  1. gdc服务器老显示drs,VMware ESXi 高可用之drs
  2. 抽奖算法-指定概率的随机
  3. URAL 1009. K-based Numbers
  4. 计算机辅助教学导学设计研究,《计算机辅助教学》实验报告
  5. 模拟退火求解TSP问题
  6. java avi转mp4_视频转GIF很麻烦?不!只需三步
  7. 判断手机号邮箱号和车牌号是否合法的方法
  8. 论文笔记-深度估计(4) Semi-Supervised Deep Learning for Monocular Depth Map Prediction
  9. 麟龙指标通达信指标公式源码_麟龙四量图通达信指标公式源码
  10. vs2008 MFC工程建立
  11. spring的注入和直接new一个对象有什么不同?
  12. 关于Hilbert矩阵的几道编程题
  13. TIMESTAMP和DATETIME的区别以及选择
  14. 路由器就能赚钱? 揭秘京东云无线宝背后的黑科技
  15. 华硕a53s拆机图解_华硕a53s配置 功能与外观描述【图解】
  16. 读取ntfs的usn
  17. pycharm中导入模块
  18. AE制作粒子飘雪效果
  19. 5.询问姓名及电话号码
  20. 工作记录(20191215)

热门文章

  1. 在Ubuntu中安装VMD
  2. 损失函数-经验风险最小化-结构风险最小化
  3. sobel算子原理以及运用
  4. Python将图片转成pdf(高清)论文党用~
  5. 数值分析与算法-喻文健-国科大
  6. 【HDU6662】Acesrc and Travel【树形DP】
  7. Python面试基础题-2018-12-26
  8. Linux的硬盘分区
  9. Linux 终端下颜色的输出
  10. Windows Server2008下MYSQL外网无法访问问题解决