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 ...
随机推荐
- 超全table功能Datatables使用的填坑之旅--2:post 动态传参: 解决: ajax 传参无值问题.
官网解释与方法:1 当向服务器发出一个ajax请求,Datatables将会把服务器请求到的数据构造成一个数据对象. 2 实际上他是参考jQuery的ajax.data属性来的,他能添加额外的参数传给 ...
- 基于zookeeper的主备切换方法
继承CZookeeperHelper即可快速实现主备切换: https://github.com/eyjian/libmooon/blob/master/include/mooon/net/zooke ...
- 计算服务器的pv量算法
如何计算服务器能够承受多大的pv? 你想建设一个能承受500万PV/每天的网站吗? 500万PV是什么概念?服务器每秒要处理多少个请求才能应对?如果计算呢? PV是什么: PV是page view ...
- (线段树 && 字符串的处理)codeforces -- 570C
链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87813#problem/J Description Daniel has a s ...
- numpy.sort()学习记录
python的功能真的是只有我想不到,没有它做不到 在学系np.sort中学到了一些 print(array2) [14 13 12 11] [10 9 8 7] [ 6 5 4 3] print(n ...
- nodejs 上传文件 upload
只是现在主要用nodejs做后端了,所以记录一些上传文件的使用方法. 上传文件的主要方式: 1.form上传,优点是方便,缺点是没法回调,上传后返回的数据没法处理 2.ajax上传,优点是可控制,有回 ...
- Java中HTTP通信
Java自带的get.post请求: get请求方式: package com.java; import java.io.BufferedReader; import java.io.IOExcept ...
- Android ListView setOnItemClickListener/setOnItemSelectedListener,无效
在Android 开发中,有时候我们在设置,LIstview,GridView,这些View的时候,再给他们设置:setOnItemClickListener/setOnItemSelectedLis ...
- 显式等待-----Selenium快速入门(十)
上一篇说了元素定位过程中的隐式等待,今天我们来探讨一下显示等待.显式等待,其实就是在使用WebDriverWait这个对象,进行等待.显式等待对比隐式等待,多了一些人性化的设置,可以说是更细化的隐式等 ...
- dorado7-发布
1.首先将configure.properties中Debug删除 2.eclipse自带的打包方式进行打包 2.1 next==>选择打包文件存放的路径==>finish==>xx ...