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 ...
随机推荐
- 551. Student Attendance Record I
static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...
- 2018.09.28 hdu5435A serious math problem(数位dp)
传送门 数位dp卡常题. 写了一发dfs版本的发现过不了233. 于是赶紧转循环版本. 预处理出f数组. f[i][j]f[i][j]f[i][j]表示前i位数异或和为j的方案数. 然后每次直接数位d ...
- hdu-1698(线段树,区间修改)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698 注意:用位运算会更快,不然超时. #include<iostream> #inclu ...
- Ubuntu在命令行开启远程桌面
在终端执行下列三个命令即可 gsettings set org.gnome.Vino enabled truegsettings set org.gnome.Vino prompt-enabled f ...
- excel如何设置自增序列
见图1 见图2 4,如果内容对您有所帮助,请打赏---1毛就足够感动我,诚信交友~
- _RecordsetPtr使用方法
_variant_t vUsername,vID,vname; //变量声明 _RecordsetPtr m_pRecordset; //记录集 CString strid; _Connect ...
- nodejs 上传文件 upload
只是现在主要用nodejs做后端了,所以记录一些上传文件的使用方法. 上传文件的主要方式: 1.form上传,优点是方便,缺点是没法回调,上传后返回的数据没法处理 2.ajax上传,优点是可控制,有回 ...
- oauth入门
oauth可以支持跨网站的数据传输.假设一个用户把照片上传到faji网站,然后想登录到beppa网站(照片打印),把faji的上照片打印出来. 她当然可以自己把照片取下来再上传上去,不过比较麻烦. 使 ...
- DevOps Workshop 研发运维一体化(成都站) 2016.05.08
成都的培训与广州.上海.北京一样,只是会议室比较小,比较拥挤,大家都将就了.可惜换了电脑以后,没有找到培训时的照片了,遗憾. 培训思路基没有太大变化,基本按照下面的思路进行: 第一天对软件开发的需求管 ...
- netcore 发布 到 windows server IIS 可能会报错
当发布netcore 到windows server iis可能会报这种错:An error occurred while starting the application 不要慌,这个时候可能是你用 ...