3. C++ POD类型
POD全称Plain Old Data,通常用于说明1个类型的属性。通俗的讲,一个类或结构体通过二进制拷贝后还能保持其数据不变,那么它就是一个POD类型。
C++11将POD划分为2个基本概念的合集,即平凡的(trivual)和标准布局的(standard layant)
1. 平凡的定义
- 有平凡的默认构造函数和析构函数。平凡的默认构造函数就是说构造函数“什么都不干”。通常情况下,不定义类的构造函数,编译器就会为我们生成一个平凡的默认构造函数。而一旦定义了构造函数,即使构造函数不包含参数,函数体也没有任何代码,那么该构造函数也不再是“平凡”的。
- 有平凡的拷贝构造函数和移动构造函数。不声明拷贝构造函数的话,编译器会自动生成,可以使用=default声明默认拷贝构造函数。
- 有平凡的拷贝赋值运算符和移动赋值运算符。
- 不能包含虚函数以及虚基类。
- 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() = ; };
- class H : G {};
- class I {};
- int main()
- {
- 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 ;
- }
2. 标准布局的定义
- 所有非静态成员有相同的访问权限
- 继承树中最多只能有一个类有非静态数据成员
- 子类的第一个非静态成员不可以是基类类型
- 没有虚函数
- 没有虚基类
- 所有非静态成员都符合标准布局类型
- 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() = ; };
- 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 ;
- }
3. POD
当一个数据类型满足了”平凡的定义“和”标准布局“,我们则认为它是一个POD数据。可以通过std::is_pod来判断一个类型是否为POD类型。一个POD类型是可以进行二进制拷贝的。
- class A
- {
- public:
- int x;
- double y;
- };
- int main()
- {
- if (std::is_pod<A>::value)
- {
- std::cout << "before" << std::endl;
- A a;
- a.x = ;
- 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;
- }
- return ;
- }
运行结果如下:
4. POD的作用
- 字节赋值,代码中我们可以安全地使用memset和memcpy对POD类型进行初始化和拷贝等操作。
- 提供对C内存布局兼容。C++程序可以与C函数进行相互操作,因为POD类型的数据在C与C++间的操作总是安全的。
- 保证了静态初始化的安全有效。静态初始化在很多时候能够提供程序的性能,而POD类型的对象初始化往往更加简单。
3. C++ POD类型的更多相关文章
- c++11 pod类型(了解)
啥是POD类型? POD全称Plain Old Data.通俗的讲,一个类或结构体通过二进制拷贝后还能保持其数据不变,那么它就是一个POD类型. 平凡的定义 .有平凡的构造函数 .有平凡的拷贝构造函数 ...
- C++ trivial和non-trivial构造函数及POD类型(转)
原博客地址http://blog.csdn.net/a627088424/article/details/48595525 最近正纠结这个问题就转过来了,做了点补充(参考<深度探索C++对象模型 ...
- 关于POD和非POD类型中,list initialization和constructor initialization(未解决)
如果你的成员是POD类型的,那么list initialization和constructor initialization没有任何区别 #include<iostream> using ...
- C++11 POD类型
POD,全称plain old data,plain代表它是一个普通类型,old代表它可以与c兼容,可以使用比如memcpy()这类c中最原始函数进行操作.C++11中把POD分为了两个基本概念的集合 ...
- POD类型
POD类型 POD全称Plain Old Data.通俗的讲,一个类或结构体通过二进制拷贝后还能保持其数据不变,那么它就是一个POD类型. C++11将POD划分为两个基本概念的合集,即:平凡的和标准 ...
- 关于C++ 中POD类型的解析
转自: http://liuqifly.spaces.live.com/blog/cns!216ae3a149106df9!221.entry (C++-98:1.8;5)给出的定义:将对象的各字节拷 ...
- C++ POD类型
POD( Plain Old Data)概念: Arithmetic types (3.9.1), enumeration types, pointer types, and pointer to m ...
- 聚合类型与POD类型
Lippman在<深度探索C++对象模型>的前言中写道: I have heard a number of people over the years voice opinions sim ...
- C++ POD 类型
POD 是 C++ 中一个比较重要的概念,POD 是英文 Plain Old Data 的缩写(通俗讲就是类或结构体通过二进制拷贝后还能保持其数据不变),用来描述一个类型(包括 class.union ...
随机推荐
- 657. Judge Route Circle
static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...
- 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_ ...
- 手机PC文件传输
QQ啥的现在直接无法全部退出,很纠结后台运行,时不时的来条消息,明明电脑QQ还开着,越来越流氓了. 服务端代码: <%@ Page Language="C#" %> & ...
- hadoop学习笔记(四):hdfs常用命令
一.hadoop fs 1.创建目录 [root@master hadoop-]# hadoop fs -mkdir /testdir1 [root@master hadoop-]# hadoop f ...
- HDU 3681 Prison Break (二分 + bfs + TSP)
题意:给定上一个 n * m的矩阵,你的出发点是 F,你初始有一个电量,每走一步就会少1,如果遇到G,那么就会加满,每个G只能第一次使用,问你把所有的Y都经过,初始电量最少是多少. 析:首先先预处理每 ...
- Java返回当前对象的好处
自己使用了一个第三方框架,发现非常的灵活,于是去研究了下,才知道是返回当前对象,才可以做到,例如以下案例: // 可以不断的点出很多函数 Glide.with(PhotoPagerSlitherAct ...
- 【WP8.1】系统控件的bug及修复方案
最近开发的时候,发现Windows Phone 8.1 Runtime中的两个控件的存在bug的情况,现总结出来,并给出解决方案. 1.Hub控件 Hub控件的顶部默认是可以拖动来切换HubSecti ...
- 我要总结基本书 .net稍微有些深度的书籍看看
1. 你必须知道的.NET 2. C# in depth 3.C#并发编程经典实例 4.ASP.NET MVC 4框架揭秘 5.NET最佳实践 6..NET探秘 .NET安全编程 .NET企业服务框架 ...
- linux系统编程之文件与IO(五):stat()系统调用获取文件信息
一.stat()获取文件元数据 stat系统调用原型: #include <sys/stat.h> int stat(const char *path, struct stat *buf) ...
- ES6 学习笔记之四 对象的扩展
ES6 为对象字面量添加了几个实用的功能,虽然这几个新功能基本上都是语法糖,但确实方便. 一.属性的简洁表示法 当定义一个对象时,允许直接写入一个变量,作为对象的属性,变量名就是属性名. 例1: , ...