广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >详解C++中普通旧数据(POD)的使用
  • 858
分享到

详解C++中普通旧数据(POD)的使用

C++普通旧数据POD使用C++普通旧数据C++旧数据 2023-03-03 14:03:38 858人浏览 薄情痞子
摘要

目录前言一、什么是普通旧数据二、使用步骤三、其他方法总结前言 在开发c++的时候,使用对象是绕不开的话题。很多时候我们关注点都在对象的“高级语义”上,比如&l

前言

开发c++的时候,使用对象是绕不开的话题。很多时候我们关注点都在对象的“高级语义”上,比如“运行时多态”,用户自定义的拷贝语义等。想象这样一种场景,给你一个含有100个对象的数组让你拷贝一份副本,正常的操作肯定是调用100次拷贝构造,但是你有没有想过一种方法,可以像拷贝char型数组那样使用内存拷贝呢?没错,这就是我们今天要讲的“普通旧数据”,简称POD。

一、什么是普通旧数据

普通旧数据就是内存中的连续字节序列,是能够被“仅当作数据”处理的对象,程序员无须顾及类布局的复杂性以及用户自定义的构造、拷贝和移动语义。

二、使用步骤

当然,不是所有的对象都满足作为普通旧数据的条件,接下来我们就具体分析下,作为普通旧数据需要满足哪些条件。先举个例子:

//普通旧数据
    struct SO { };// 是 POD
    struct S1 { int a; };// 是 POD
    struct S2 { int a; S2(int aa) : a(aa) { } };//不是 POD (不是默认构造函数)
    struct S3 { int a; S3(int aa) : a(aa) { } S3() {} };//是 POD (用户自定义的默认构造函数)
    struct S4 { int a; S4(int aa) : a(aa) { } S4() = default; };//是 POD
    struct S5 { virtual void f();  };//不是 POD (含有一个虚函数)
    struct S6 : S1 { };// 是 POD
    struct S7 : SO { int b; };// 是 POD
    struct S8 : S1 { int b; };//不 是 POD (数据既属于S1也属于S8)
    struct S9 : SO, S1 {};// 是 POD

上面的例子几乎涵盖了普通旧数据能遇到的所有场景。然而我们如果想把某个对象“仅当作数据”处理(当作POD),则要求该对象必须满足下述条件:

1.不具有复杂的布局,比如含有虚函数。

2.不具有非标准(用户自定义的)拷贝语义。

3.含有一个最普通的默认构造函数。

这里的含有一个最普通的构造函数是指“必要条件”,同时你也可以自定义一个构造函数。

显然,我们在定义POD时必须非常谨慎,从而确保在不破坏任何语言规则的前提下使用这些优化措施。正式的规定是(§iso.3.9,§iso.9):POD必须是属于下列类型的对象:

1.标准布局类型(standard layout type)

2.平凡可拷贝类型(trivially copyable type)

3.具有平凡默认构造函数的类型

一个与之有关的概念是平凡类型(trivial type),它具有以下属性:

1.一个平凡默认构造函数

2.平凡拷贝和移动操作

通俗地说,当一个默认构造函数无须执行任何实际操作时(如果需要定义一个默认构造函数,使用=default,保持默认行为),那么他就是平凡构造函数。

那么,什么样的布局是标准布局呢?考虑以下几种情形不满足标准布局的要求:

1.含有一个非标准布局的非static成员或基类;

2.包含virtual函数

3.包含virtual基类

4.含有引用类型

5.其中的非静态数据成员有多种访问修饰符

6.阻止了重要的布局优化:在多个基类中都含有非static数据成员,或者在派生类和基类中都含有非static数据成员,或者基类类型与第一个非static数据成员的类型相同。

基本上,标准布局类型是指与C语言的布局兼容的类型,并且应该能被常规的C++应用程序二进制接口(ABI)处理。

除非在类型内部含有非平凡的拷贝操作、移动操作或者析构函数,否则该类型就是平凡可拷贝的类型。通俗地说,如果一个拷贝操作能被实现成逐位拷贝的形式,则它是平凡的。那么,哪些情形下让拷贝、移动和析构函数变得不平凡呢?

1.这些操作是用户定义的。

2.这些操作所属的类含有virtual函数。

3.这些操作所属的类含有virtual基类。

4.这些操作所属的类含有非平凡的基类或者成员。

内置类型的变量都是平凡可拷贝的,且拥有标准布局。同样,由平凡可拷贝对象组成的数组是平凡可拷贝的,由标准布局对象组成的数组拥有标准布局。

三、其他方法

说了那么多概念,感觉人都疯了,想要记住这些概念真的是不容易。好在C++标准库帮我们实现了一个类型属性谓词is_pod。有了这个东西,我还记那些繁琐的规则干什么呢?下面是使用方法,特别简单。

std::is_pod<T> //T 是POD吗,是或不是

std::cout << std::is_pod<int>::value << std::endl; //value is bool

//示例
template<typename T>
void my_copy(T *to, const T *from, int count) {
    if (is_pod<T>::value)
        memcpy(to, from, count*sizeof(T));
    else
        for (int i = 0; i < count; ++i) {
            to[i] = from[i];
        }
}

总结

1.规则相当复杂,但是努力还是记得住的。

2.不需要记复杂的规则,直接使用is_pod

3.如果你确实对C++语言的深层次内容有非常浓厚的兴趣,不妨花点时间研究一下C++标准中对布局和平凡性概念的规定(§iso.3.9,§iso.9)

到此这篇关于详解C++中普通旧数据(POD)的使用的文章就介绍到这了,更多相关C++普通旧数据内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 详解C++中普通旧数据(POD)的使用

本文链接: https://www.lsjlt.com/news/198394.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 详解C++中普通旧数据(POD)的使用
    目录前言一、什么是普通旧数据二、使用步骤三、其他方法总结前言 在开发C++的时候,使用对象是绕不开的话题。很多时候我们关注点都在对象的“高级语义”上,比如&l...
    99+
    2023-03-03
    C++普通旧数据POD使用 C++普通旧数据 C++ 旧数据
  • C++中普通旧数据怎么使用
    本篇内容主要讲解“C++中普通旧数据怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++中普通旧数据怎么使用”吧!一、什么是普通旧数据普通旧数据就是内存中的连续字节序列,是能够被“仅当作...
    99+
    2023-07-05
  • 详解C#中普通缓存的使用
    目录一、首先,新建控制台程序(.NET Core)、以下为项目结构二、编写缓存类三、编写有缓存和没有缓存方法四、控制台上端调用总结一下哈:一、首先,新建控制台程序(.NET Core...
    99+
    2022-11-12
  • 详解Python中的普通函数和高阶函数
    目录什么是函数函数的嵌套调用高阶函数我们思考一下计算圆形和方形的面积为何高阶函数能够降低维度总结什么是函数 每个语言都有函数,甚至大家用的Excel里面也有函数,我们以前学习的数学也...
    99+
    2022-11-12
  • linux中普通用户的定时任务详解
    前言 普通用户定义crontab定时任务:比如oracle用户定义一个定时任务:每分钟打印当前目录 [oracle@node2 ~]$ crontab -e */1 * * * * /bin/ls -al >...
    99+
    2022-06-04
    linux普通用户 linux普通用户的定时任务
  • JavaScript中箭头函数与普通函数的区别详解
    本文为大家讲解了JavaScript中箭头函数与普通函数的区别,供大家参考,具体内容如下 箭头函数: let fun = () => { console.log('...
    99+
    2022-11-12
  • c++ 数据结构map的使用详解
    目录map的常用用法 1. 头文件2. 定义 3. map 容器内元素的访问 (1)通过下标访问 (2)通过迭代器访问 (3)通过逆向迭代器访问4. map 元素的插入 5. map...
    99+
    2022-11-12
  • JS函数(普通函数,箭头函数)中this的指向问题详解
    目录普通函数箭头函数普通函数 具名普通函数、匿名普通函数,在不作为对象的属性值的情况下,其内部的 this 总是指向代码运行环境下的全局对象 ( 例如,浏览器中的 window )。...
    99+
    2022-11-13
  • C/C++中extern函数使用详解
    目录一、定义和声明的区别二、extern用法2.1 extern 函数2.2 extern 变量2.3 在C++文件中调用C方式编译的函数三、通俗讲解extern一、定义和声明的区别...
    99+
    2022-11-13
  • 详解C++中的数据抽象
    目录C++ 数据抽象访问标签强制抽象数据抽象的好处数据抽象的实例设计策略C++ 数据抽象 数据抽象是指,只向外界提供关键信息,并隐藏其后台的实现细节,即只表现必要...
    99+
    2023-05-19
    C++抽象 C++数据抽象
  • 如何使用Go语言中的普通的函数
    本篇内容主要讲解“如何使用Go语言中的普通的函数”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何使用Go语言中的普通的函数”吧!普通函数在 Go 语言中普通函数的定义格式为 func [函数名...
    99+
    2023-06-15
  • 数据库中如何查询所有的普通用户
    这篇文章主要介绍了数据库中如何查询所有的普通用户,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。查询数据库中的所有的普通用户:selec...
    99+
    2022-10-18
  • C/C++中时间库函数的使用详解
    目录C/C++ 中时间的概念常用的时间库函数time()asctime()gmtime()ctime()localtime()mktime()difftime()C/C++ 获取当前...
    99+
    2022-11-13
    C/C++时间库函数 C/C++时间函数 C++ 时间函数
  • C#的通用DbHelper类(支持数据连接池)示例详解
    每次新项目的时候,都要从头去找一遍数据库工具类。这里分享一个简单实用的C#的通用DbHelper工具类,支持数据连接池。 连接池配置 <connectionStrings>...
    99+
    2022-11-13
  • C语言中数组的使用详解
    目录1 数组的基本概念2 数组定义语法3 一维数组的初始化3.1 全部初始化3.2 部分元素赋初值3.3 省略长度赋初值4 一维数组的使用示例4.1 求最大值、最小值、平均值4.2 ...
    99+
    2022-11-12
  • Oracle数据库中通用的函数实例详解
    目录一、 Scott用户下的表结构1、如果自己没有Scoot表就可以自己创建一个二、单行函数1、字符函数2、数值函数三、多行函数(聚合函数)1、统计记录数2、最小值查询 min()3...
    99+
    2022-11-13
  • C语言中数据的存储详解
    目录1.内置类型(1)整型数组(2)浮点型2.自定义类型3.指针类型4.空类型(void)字符型浮点型(一)(二)总结 数据的存储首先就要说到数据的类型,类型决定了看待内存空间的视角...
    99+
    2022-11-12
  • C++中的数据对齐示例详解
    前言 对于C/C++程序员来说,掌握数据对齐是很有必要的,因为只有了解了这个概念,才能知道编译器在什么时候会偷偷的塞入一些字节(padding)到我们的结构体(struct/clas...
    99+
    2022-11-11
  • 详解C语言中数据的存储
    目录一、类型归类1、整形家族2、浮点型家族3、指针类型4、空类型二、类型的意义 三、数据在类型中存储(以整形和浮点型为例子)1. 关于 存储的基本概念2.存储模式四.应用1.2.对...
    99+
    2022-11-12
  • C++中gSOAP的使用详解
    目录SOAP简介gSOAP准备工作头文件构建客户端应用程序生成soap源码建立客户端项目构建服务端应用程序生成SOAP源码建立服务端项目打印报文SOAP测试项目源码总结本文主要介绍C...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作