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 ...
随机推荐
- IC向管理者角色转换
1. 虽然你认为自己已经想明白怎么干,但还是从怎么干回归到要解决的问题,抛给正确的人(应该对这些问题负责的人),引导他们想出问题的答案. 给别人机会和空间,帮助他们成长: 人们对自己“想”出的方案更有 ...
- 2018.09.26洛谷P1084 疫情控制(二分+倍增)
传送门 好题啊. 题目要求的最大值最小,看到这里自然想到要二分答案. 关键在于怎么检验. 显然对于每个点向根走比向叶节点更优. 因此我们二分答案之后,用倍增将每个点都向上跳到跳不动为止. 这时我们ch ...
- 2018.09.15 poj2117Electricity(割点)
传送门 其实求一个图删除一个点之后,联通块最多有多少. 直接tarjan求割点更新答案就行了. 但注意原图不一定连通. 代码: #include<iostream> #include< ...
- 第七章 介词(La préposition )
法语中的介词是将两个同类或非同类的词连接在一起,把一个句中成分同另一个句子成分联系起来,并表明两者之间关系的词类.介词是一种无词性变化的词类. ★介词的形式 ()简单形式的介词,如: ()复合形式的介 ...
- 删除k8s中一直处于Terminating的资源
1.将所有的etcd中的key值取到一个keys.yam里面,便于查询 ETCDCTL_API=3 etcdctl get "" --from-key > keys.yaml ...
- UVa 11732 "strcmp()" Anyone? (左儿子右兄弟前缀树Trie)
题意:给定strcmp函数,输入n个字符串,让你用给定的strcmp函数判断字符比较了多少次. 析:题意不理解的可以阅读原题https://uva.onlinejudge.org/index.php? ...
- python编码(六)
1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有 ...
- MySQL性能调优与架构设计——第12章 可扩展设计的基本原则
第12章 可扩展设计的基本原则 前言: 随着信息量的飞速增加,硬件设备的发展已经慢慢的无法跟上应用系统对处理能力的要求了.此时,我们如何来解决系统对性能的要求?只有一个办法,那就是通过改造系统的架构体 ...
- Breaseman算法绘制圆形|中点算法绘制圆形_程序片段
Breaseman算法绘制圆形|中点算法绘制圆形_程序片段 1. Breaseman算法绘制圆形程序 由于算法的特殊性,限制绘制第一象限部分,其他部分通过旋转绘制. void CCGProjectWo ...
- Socket常用语法与socketserver实例
1>Socket相关: 1>Socket Families(地址簇): socket.AF_UNIX 本机进程间通信 socket.AF_INET IPV4 socket.AF_I ...