POD全称Plain Old Data,通常用于说明1个类型的属性。通俗的讲,一个类或结构体通过二进制拷贝后还能保持其数据不变,那么它就是一个POD类型。

C++11将POD划分为2个基本概念的合集,即平凡的(trivual)和标准布局的(standard layant)

1. 平凡的定义

  • 有平凡的默认构造函数和析构函数。平凡的默认构造函数就是说构造函数“什么都不干”。通常情况下,不定义类的构造函数,编译器就会为我们生成一个平凡的默认构造函数。而一旦定义了构造函数,即使构造函数不包含参数,函数体也没有任何代码,那么该构造函数也不再是“平凡”的。
  • 有平凡的拷贝构造函数和移动构造函数。不声明拷贝构造函数的话,编译器会自动生成,可以使用=default声明默认拷贝构造函数。
  • 有平凡的拷贝赋值运算符和移动赋值运算符。
  • 不能包含虚函数以及虚基类。
  1. class A { A(){} };
  2. class B { B(B&){} };
  3. class C { C(C&&){} };
  4. class D { D operator=(D&){} };
  5. class E { E operator=(E&&){} };
  6. class F { ~F(){} };
  7. class G { virtual void foo() = ; };
  8. class H : G {};
  9. class I {};
  10.  
  11. int main()
  12. {
  13. std::cout << std::is_trivial<A>::value << std::endl; // 有不平凡的构造函数
  14. std::cout << std::is_trivial<B>::value << std::endl; // 有不平凡的拷贝构造函数
  15. std::cout << std::is_trivial<C>::value << std::endl; // 有不平凡的拷贝赋值运算符
  16. std::cout << std::is_trivial<D>::value << std::endl; // 有不平凡的拷贝赋值运算符
  17. std::cout << std::is_trivial<E>::value << std::endl; // 有不平凡的移动赋值运算符
  18. std::cout << std::is_trivial<F>::value << std::endl; // 有不平凡的析构函数
  19. std::cout << std::is_trivial<G>::value << std::endl; // 有虚函数
  20. std::cout << std::is_trivial<H>::value << std::endl; // 有虚基类
  21.  
  22. std::cout << std::is_trivial<I>::value << std::endl; // 平凡的类
  23.  
  24. return ;
  25. }

2. 标准布局的定义

  • 所有非静态成员有相同的访问权限
  • 继承树中最多只能有一个类有非静态数据成员
  • 子类的第一个非静态成员不可以是基类类型
  • 没有虚函数
  • 没有虚基类
  • 所有非静态成员都符合标准布局类型
  1. class A
  2. {
  3. private:
  4. int a;
  5. public:
  6. int b;
  7. };
  8.  
  9. class B1
  10. {
  11. static int x1;
  12. };
  13.  
  14. class B2
  15. {
  16. int x2;
  17. };
  18.  
  19. class B : B1, B2
  20. {
  21. int x;
  22. };
  23.  
  24. class C1 {};
  25. class C : C1
  26. {
  27. C1 c;
  28. };
  29.  
  30. class D { virtual void foo() = ; };
  31. class E : D {};
  32. class F { A x; };
  33.  
  34. int main()
  35. {
  36. std::cout << std::is_standard_layout<A>::value << std::endl; // 违反定义1。成员a和b具有不同的访问权限
  37. std::cout << std::is_standard_layout<B>::value << std::endl; // 违反定义2。继承树有两个(含)以上的类有非静态成员
  38. std::cout << std::is_standard_layout<C>::value << std::endl; // 违反定义3。第一个非静态成员是基类类型
  39. std::cout << std::is_standard_layout<D>::value << std::endl; // 违反定义4。有虚函数
  40. std::cout << std::is_standard_layout<E>::value << std::endl; // 违反定义5。有虚基类
  41. std::cout << std::is_standard_layout<F>::value << std::endl; // 违反定义6。非静态成员x不符合标准布局类型
  42.  
  43. return ;
  44. }

3. POD

当一个数据类型满足了”平凡的定义“和”标准布局“,我们则认为它是一个POD数据。可以通过std::is_pod来判断一个类型是否为POD类型。一个POD类型是可以进行二进制拷贝的。

  1. class A
  2. {
  3. public:
  4. int x;
  5. double y;
  6. };
  7.  
  8. int main()
  9. {
  10. if (std::is_pod<A>::value)
  11. {
  12. std::cout << "before" << std::endl;
  13. A a;
  14. a.x = ;
  15. a.y = 10.5;
  16. std::cout << a.x << std::endl;
  17. std::cout << a.y << std::endl;
  18.  
  19. size_t size = sizeof(a);
  20. char *p = new char[size];
  21. memcpy(p, &a, size);
  22. A *pA = (A*)p;
  23.  
  24. std::cout << "after" << std::endl;
  25. std::cout << pA->x << std::endl;
  26. std::cout << pA->y << std::endl;
  27.  
  28. delete p;
  29. }
  30.  
  31. return ;
  32. }

运行结果如下:

4. POD的作用

  • 字节赋值,代码中我们可以安全地使用memset和memcpy对POD类型进行初始化和拷贝等操作。
  • 提供对C内存布局兼容。C++程序可以与C函数进行相互操作,因为POD类型的数据在C与C++间的操作总是安全的。
  • 保证了静态初始化的安全有效。静态初始化在很多时候能够提供程序的性能,而POD类型的对象初始化往往更加简单。

3. C++ POD类型的更多相关文章

  1. c++11 pod类型(了解)

    啥是POD类型? POD全称Plain Old Data.通俗的讲,一个类或结构体通过二进制拷贝后还能保持其数据不变,那么它就是一个POD类型. 平凡的定义 .有平凡的构造函数 .有平凡的拷贝构造函数 ...

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

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

  3. 关于POD和非POD类型中,list initialization和constructor initialization(未解决)

    如果你的成员是POD类型的,那么list initialization和constructor initialization没有任何区别 #include<iostream> using ...

  4. C++11 POD类型

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

  5. POD类型

    POD类型 POD全称Plain Old Data.通俗的讲,一个类或结构体通过二进制拷贝后还能保持其数据不变,那么它就是一个POD类型. C++11将POD划分为两个基本概念的合集,即:平凡的和标准 ...

  6. 关于C++ 中POD类型的解析

    转自: http://liuqifly.spaces.live.com/blog/cns!216ae3a149106df9!221.entry (C++-98:1.8;5)给出的定义:将对象的各字节拷 ...

  7. C++ POD类型

    POD( Plain Old Data)概念: Arithmetic types (3.9.1), enumeration types, pointer types, and pointer to m ...

  8. 聚合类型与POD类型

    Lippman在<深度探索C++对象模型>的前言中写道: I have heard a number of people over the years voice opinions sim ...

  9. C++ POD 类型

    POD 是 C++ 中一个比较重要的概念,POD 是英文 Plain Old Data 的缩写(通俗讲就是类或结构体通过二进制拷贝后还能保持其数据不变),用来描述一个类型(包括 class.union ...

随机推荐

  1. 657. Judge Route Circle

    static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...

  2. 2018.09.27 codeforces618F. Double Knapsack(抽屉原理+构造)

    传送门 思维题. 考虑维护两个数列的前缀和a1,a2,a3,...,ana_1,a_2,a_3,...,a_na1​,a2​,a3​,...,an​和b1,b2,b3,...,bnb_1,b_2,b_ ...

  3. 手机PC文件传输

    QQ啥的现在直接无法全部退出,很纠结后台运行,时不时的来条消息,明明电脑QQ还开着,越来越流氓了. 服务端代码: <%@ Page Language="C#" %> & ...

  4. hadoop学习笔记(四):hdfs常用命令

    一.hadoop fs 1.创建目录 [root@master hadoop-]# hadoop fs -mkdir /testdir1 [root@master hadoop-]# hadoop f ...

  5. HDU 3681 Prison Break (二分 + bfs + TSP)

    题意:给定上一个 n * m的矩阵,你的出发点是 F,你初始有一个电量,每走一步就会少1,如果遇到G,那么就会加满,每个G只能第一次使用,问你把所有的Y都经过,初始电量最少是多少. 析:首先先预处理每 ...

  6. Java返回当前对象的好处

    自己使用了一个第三方框架,发现非常的灵活,于是去研究了下,才知道是返回当前对象,才可以做到,例如以下案例: // 可以不断的点出很多函数 Glide.with(PhotoPagerSlitherAct ...

  7. 【WP8.1】系统控件的bug及修复方案

    最近开发的时候,发现Windows Phone 8.1 Runtime中的两个控件的存在bug的情况,现总结出来,并给出解决方案. 1.Hub控件 Hub控件的顶部默认是可以拖动来切换HubSecti ...

  8. 我要总结基本书 .net稍微有些深度的书籍看看

    1. 你必须知道的.NET 2. C# in depth 3.C#并发编程经典实例 4.ASP.NET MVC 4框架揭秘 5.NET最佳实践 6..NET探秘 .NET安全编程 .NET企业服务框架 ...

  9. linux系统编程之文件与IO(五):stat()系统调用获取文件信息

    一.stat()获取文件元数据 stat系统调用原型: #include <sys/stat.h> int stat(const char *path, struct stat *buf) ...

  10. ES6 学习笔记之四 对象的扩展

    ES6 为对象字面量添加了几个实用的功能,虽然这几个新功能基本上都是语法糖,但确实方便. 一.属性的简洁表示法 当定义一个对象时,允许直接写入一个变量,作为对象的属性,变量名就是属性名. 例1: , ...