跟我学C++中级篇——POD数据类型及演进

一、POD数据类型

首先说明,所谓POD类型不是常说的标准中的int,double这种数据类型。它是一种与C语言兼容的类型,能够直接以二进制形式与C库进行交互。这样说可能不好理解,意思就是说它可以直接使用memcpy,memmove等函数进行赋值。 POD(Plain Old Data,简旧数据)类型,是一种C++与C标准兼容的数据类型统称。用官话说:“This is a type category defined by the core language. It is included here as a named requirement only for consistency.”
在C++11以后,C++又定义了几种此种类型的类型,即平凡类型 (TrivialType) ,标量类型 (ScalarType) 和标准布局类型 (StandardLayoutType) 。所以需要注意的是,在新的C++20标准中,此种数据类型已经不再使用,即不再使用POD称呼这种类型,而不是说这种类型的数据真的不存在了。
那么什么样的数据类型可以被认为是POD数据类型呢:
1、标量类型
2、POD 类
3、上述类型的数组
4、这些类型的有 cv 限定版本
POD类的定义:
C++11标准前:
1、它是聚合体
2、没有用户声明的复制赋值运算符
3、没有用户声明的析构函数,并且没有具有非 POD 类类型(或这种类型的数组)或者引用类型的非静态数据成员。
C++11标准后:
4、它不但是平凡类,还是标准布局类(trivial and stdlayout),并且没有具有非 POD 类类型(或这种类型的数组)的非静态数据成员。
POD 结构体 是非联合体的 POD 类。POD 联合体 是满足 POD 类条件的联合体。
再看一下什么是聚合体:
1、数组类型
2、符合以下条件的类类型:
没有用户声明的构造函数 (C++11 前)
没有用户提供、继承或 explicit 的构造函数 (C++11 ~C++20)
没有用户声明或继承的构造函数 (C++20 起)
没有私有或受保护的直接 非静态数据成员 (C++17 起)
没有基类 (C++17 前)
没有虚基类(C++17 起)
没有私有或受保护的直接基类 (C++17 起)
没有虚成员函数
没有默认成员初始化器 (C++11~C++14 )

这样就可以得出POD数据类型的特点是:它是平坦且连续的内存,可以嵌套但非静态成员变量必须也是POD类型(污染扩展),可以放心的使用C库中的函数进行操作。静态成员属于类作用域,不是对象的属性,所以其不影响一个类或结构体是否为POD类型。

二、平凡类型 (TrivialType)

在前文“c++中的trivial”对平凡类型进行了基础的介绍和分析,这里再简要说明一遍。平凡类型包括:“ 标量类型,平凡类类型,上述类型的数组,这些类型的有 cv限定版本”。这里重点介绍一下平凡类。它是满足以下所有条件的类:它是可平凡复制类,并且有一个或多个合格的默认构造函数,它们全部都是平凡的。 而平凡复制类就是指符合下面的条件的类:
1、至少有一个合格的复制构造函数,移动构造函数,复制赋值运算符或移动赋值运算符
2、每个合格的复制构造函数都是平凡的
3、每个合格的移动构造函数都是平凡的
4、每个合格的复制赋值运算符都是平凡的
5、每个合格的移动赋值运算符都是平凡的,并且有一个未被弃置的平凡析构函数
而所谓平凡是指:
1、它不是用户提供的(即它是隐式定义或预置的)
2、类型T 没有虚成员函数
3、类型T 没有虚基类
4、为 T 的每个直接基类选择的移动构造函数都是平凡的
5、为 T 的每个类类型(或类类型数组)的非静态成员选择的移动构造函数都是平凡的
说白了就是可以兼容C库中的memset,memmove等操作的,连续内存空间地址的类型。或说用一句不太准确的大白话来说,在C++中类默认有六个函数(默认构造、析构、赋值、拷贝、移动拷贝、移动赋值),它们都是使用默认而非用户显示定义的。即这六个函数只是一个符合标准的架子,不参与额外的动作。

三、标量类型 (ScalarType)

这个类型最好理解,其实就是标准里定义的基础数据类型即:
1、算术类型
2、枚举类型
3、指针类型
4、成员指针类型
5、std::nullptr_t (C++11 起)
6、这些类型的有 cv 限定版本

四、标准布局类型 (StandardLayoutType)

这就需要明白什么是标准布局:
当且仅当类是 POD 类时它被当成是标准布局 的。POD类刚刚已经介绍了。
它有以下几种:
1、标量类型
2、标准布局类类型
3、上述类型的数组
4、这些类型的有 cv 限定版本
简单介绍一下标准布局类类型:
1、没有具有非标准布局类类型(或这种类型的数组)或引用类型的非静态数据成员
2、没有虚函数和虚基类
3、所有非静态数据成员都具有相同的可访问性
4、没有非标准布局的基类
5、继承层级中仅有一个类具有非静态数据成员,并且简单的限定,该类的所有基类的类型均不同于第一个非静态数据成员,准确的限定见标准文档
标准布局意味着可以和不同的语言之间进行互操作。这个非常好理解,原来写动态库的接口导出时,在Windows平台上就有各种定义接口导出方式,这个本质是相同的。再结合平凡的类型是连续递增的地址空间,而POD类型是这两个的共同要求,这样就可以明白,为什么C语言的数据结构体可以在不同的语言和平台上进行交互的原因了吧。

五 、总结

现在都知道数据是资产了,数据的定义就有数据类型,可以看这几种类型当成一种更抽象的层次的数据类型。怎么理解这句话呢?可以把常见的各种语言中的数据类型定义(如int,float等 )当成普通数据类型,而上面分析的数据类型理解为这些数据类型以上的更高层次的抽象。只要满足了特定的要求,就可以将其理解为这种数据类型。绕来绕去,真麻烦。
这些数据类型有什么 用处呢?其实是兼容扩展,能够和其它语言保持数据交互,这其实是相当重要的。沟通几乎能治百病,慢慢理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/836170.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java异常,日志,线程堆栈与Jvm调优

一.知识目录: 二.什么是java异常: 2.1 Throwable类中的重要方法: (1)四个构造方法(用来构造throwable对象,不同构造方法可以传递不同的参数值): /** 构造一个将 null 作为其详细消息的新 throwable */ Thr…

在STM32中用寄存器方式点亮流水灯

文章目录 实验资料一、对寄存器的理解1.通俗认识寄存器2.深入了解寄存器(1)端口配置低寄存器(配置0到7引脚的寄存器)(2)端口配置高寄存器(配置8到15引脚) 3.GPIO口的功能描述 二、配…

鸿蒙内核源码分析(Shell解析篇) | 应用窥视内核的窗口

系列篇从内核视角用一句话概括shell的底层实现为:两个任务,三个阶段。其本质是独立进程,因而划到进程管理模块。每次创建shell进程都会再创建两个任务。 客户端任务(ShellEntry): 负责接受来自终端(控制台)敲入的一个个字符&…

【云原生】 Kubernetes核心概念

目录 引言 一、部署方式回溯 (一)传统部署时代 (二)虚拟化部署时代 (三)容器部署时代 二、Kubernetes基本介绍 (一)为什么使用k8s (二)主要功能 &am…

以AI对抗AI,瑞数“动态安全+AI”助力在线反欺诈

勒索病毒、恶意软件、网络钓鱼攻击……科技头条每天都充斥着各种网络威胁的故事。同时,AI大模型等技术的加快发展,让网络威胁花样百出,有些明目张胆,有些则“锦衣夜行”,愈发难以识别和防范,为方兴未艾的数…

乡村振兴与数字乡村建设:加强农村信息化建设,推动数字乡村发展,提升乡村治理和服务水平,构建智慧化的美丽乡村

目录 一、引言 二、数字乡村建设的必要性 1、推动农村经济转型升级 2、提升乡村治理水平 3、改善乡村民生福祉 三、数字乡村建设的现状与挑战 1、现状 2、挑战 四、数字乡村建设的未来发展路径 1、加强农村信息化基础设施建设 2、提升农民信息素养和技能水平 3、制…

css 实现背景图和背景色正片叠底

.style {background-image: url(https://xxx.png);background-repeat: no-repeat;background-position: right center;background-color: rgb(3, 124, 207);border-bottom: 2px solid rgb(4, 83, 162);color: rgb(255, 255, 255);background-blend-mode: multiply; /*或者 col…

py黑帽子学习笔记_环境准备

1 下载os装os 下载一个kali虚机镜像然后用虚机管理软件创虚机,装完如下图,我用的版本是2024.1的版本kali-linux-2024.1-installer-amd64,可以从镜像站下载,官网下的慢还断网Index of /kali-images/kali-2024.1/ | 清华大学开源软…

OceanBase V4.2 特性解析:用Values Statement 语法进行SQL优化

1. 背景 你是否也遭遇过这样的场景:在输出多行多列表格数据时,却受限于只能依赖多 UNION ALL 语句来实现。在实际的工程应用中,我们也观察到有些用户程序生成的 SQL 语句中含有大量的 UNION ALL,这种结构的 SQL 对于 OceanBase 数…

C++高精度算法-加法

引子 在C++的运算中,难免会出现很大很大的数,下面是各个关键字的表示范围 但是如果要表示的数超过了long long可以表示的最大值( 2 64 2^{64} 264-1) 怎么办呢? 如果强制表示,就会溢出,这里的溢出大家可以自行百度,反正就是会出一些-5665434之类的数 现在,就要切入正…

网络基础-Telnet协议

Telnet(Telecommunication Network)是一种基于文本的远程终端协议,允许用户通过网络连接到远程计算机,并在远程计算机上执行命令;它使用TCP作为传输层协议,并依赖于网络连接在客户端和服务器之间进行通信&a…

MySQL 身份认证漏洞 CVE-2012-2122

漏洞影响版本 MariaDB versions from 5.1.62, 5.2.12, 5.3.6, 5.5.23 are not.MySQL versions from 5.1.63, 5.5.24, 5.6.6 are not.演示 开启靶场 进入漏洞目录 cd /root/vulhub/mysql/CVE-2012-2122开启漏洞靶场 docker-compose up -d攻击 直接 运行 这个命令 for i i…

监听进程结束并自动运行新进程与虚拟环境智能切换的sh脚本

文章目录 前言一、等待进程结束自动运行新进程二、智能环境切换总结 前言 在编程中,等待进程结束或许是一个很长时间,特别是深度学习。那么这种等待发生在晚上是一个不友好现象,为避免等待情况。我写了一个sh脚本,帮助监听PID&am…

分布式与一致性协议之PBFT算法(二)

PBFT算法 如何替换作恶的主节点 虽然PBFT算法可以防止备份节点作恶,因为这个算法是由主节点和备份节点组成的,但是,如果主节点作恶(比如主机点接收到了客户端的请求,但就是默不作声,不执行三阶段协议),那…

Line Buffer概述

buffer在芯片物理上一般指的是SRAM,也可以指寄存器组。buffer的作用是用来在逻辑芯片上暂时存储数据,但不会是大量的数据。如果是大量数据一般会使用DRAM(典型的指DDR)作为存储芯片,用来存储大密度数据。line buffer可…

优化资源利用,用C++内存池点亮编程之路

内存池介绍(Memory Pool): 它是一种内存分配方式,通过预先分配和复用内存块。 在真正使用内存之前,先申请一大块内存备用。当有新的内存需求时,就从内存池中分出一部分内存块, 若内存块不够再继续申请新的内存。如果我们不需要…

环形链表(判断链表中是否有环)的讲解

一:题目 二:思路讲解 1:采用快慢指针的方法,一个fast指针一次移动两个节点,一个slow指针一次移动一个节点。 2:两个指针从头指针开始往后遍历,如果fast指针或者fast->next 有一个为空&…

5款可用于LLMs的爬虫工具/方案

5款可用于LLMs的爬虫工具/方案 Crawl4AI 功能: 提取语义标记的数据块为JSON格式,提供干净的HTML和Markdown文件。 用途: 适用于RAG(检索增强生成)、微调以及AI聊天机器人的开发。 特点: 高效数据提取,支持LLM格式,多U…

c++ 入门2

目录 五. 函数重载 1、参数类型不同 2、参数个数不同 3、参数类型顺序不同 C支持函数重载的原理--名字修饰(name Mangling) 为什么C支持函数重载,而C语言不支持函数重载呢? 六. 引用 6.1 概念 6.2 引用特性 6.3 常引用 6.4 使用场景 …

美国政府发布新的国际网络空间和数字政策战略(下)

文章目录 前言五、当前时期的特征六、战略的畅想前言 该战略提出,2020年代是决定性的十年,当前采取的行动将塑造未来网络空间、数字技术和数字经济的“轮廓”;在实施该战略时,美国务院将与国会和机构间合作伙伴合作,评估当前的网络授权,并根据需要修改或创建授权,以便跟…