C++ 普通旧数据解读(POD)

2023-05-16

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、什么是普通旧数据?
  • 二、使用步骤
  • 三、其他方法
  • 总结


前言

在开发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)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 普通旧数据解读(POD) 的相关文章

  • k8s删除pod失败,一直处于deleted的界面

    我们在删除pod的时候出现以下情况 xff1a span class token comment 删除pod span span class token punctuation span root 64 master1 yaml span
  • k8s与pod概念

    此文章为学习过程中根据网上资源整合总结 文章目录 1 为什么需要k8s1 1 应用部署模式的演进1 11 模式对比1 12 各模块介绍 1 2 管理大量的容器 k8s 2 ks8的集群架构3 pod k8s调度的最小单元3 1 一个 pod
  • k8s pod OOMKilled 错误原因

    k8s oomkilled 错误原因 xff1a 容器使用的内存资源超过了限制 只要节点有足够的内存资源 xff0c 那容器就可以使用超过其申请的内存 xff0c 但是不允许容器使用超过其限制的资源 在yaml文件的resources li
  • k8s核心概念 pod调度和生命周期

    文章目录 调度约束方法nodeNamenodeSelector Pod调度流程pod生命周期生命周期概述 pod生命周期流程容器启动容器终止容器重启策略回顾容器生命周期 健康检查健康检查方式Probe探测方式探测方式举例liveness e
  • kubernetes Pod高级用法-探针

    POD 2高级用法 容器探测详解 所谓容器探测就是我们在里面设置了一些探针 xff0c 或者传感器来获取相应的数据用来判断容器存活与否或者就绪与否的标准 xff1b 目前k8s支持的存活性探测方式和就绪性探测方式都是一样的 xff0c 探针
  • k8s 防止pod调度到同一节点

    参考节点亲和性 xff0c pod affinity 可以这样理解 xff1a 调度的时候选择 xff08 或者不选择 xff09 这样的节点 N xff0c 这些节点上已经运行了满足条件 X 条件 X 是一组 label 选择器 xff0
  • C++ 普通旧数据解读(POD)

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 什么是普通旧数据 xff1f 二 使用步骤三 其他方法总结 前言 在开发C 43 43 的时候 xff0c 使用对象是绕
  • k8s 怎么修改pod所在的子网cidr

    如果你想修改 pod 所在的子网 CIDR xff0c 你需要修改 kubernetes 集群的网络配置 这通常是由集群管理员来完成的 xff0c 因为修改网络配置可能会影响集群中的所有节点和 pod 要修改网络配置 xff0c 你需要使用
  • K8S内部pod之间相互调用案例和详解

    目录 一 部署nginx容器 二 部署tomcat服务 三 使用nginx代理tomcat服务 四 测试 服务发现简介 xff1a 1 service是用于K8S的服务发现的重要组件 xff0c pod作为运行业务的承载方式 xff0c 要
  • 玩转k8s(四)—— 通过Service访问Pod

    我们不应该期望k8s Pod是健壮的 xff0c 而是要假设Pod中的容器很可能因为各种原因发生故障而死掉 Deployment等Controller会通过动态的创建和销毁Pod来保证应用整体的健壮性 换句话说 xff0c Pod是脆弱的
  • Pod提示NetworkPlugin cni failed to set up .. network:open/run/flannel/subnet.env:nosuchfileordirectory

    K8s在创建pod时发现pod状态为ContainerCreating状态 检查pod的日志发现提示 Failed create pod sandbox rpc error code 61 Unknown desc 61 failed to
  • kubernetes单个pod运行两个容器yaml文件实践

    kubernetes单个pod运行两个容器yaml文件实践 1 rc的yaml文件 apiVersion v1 kind Replicationtroller metadate name baolei rc spec replicas 1
  • kubernetes flannel pod CrashLoopBackoff解决

    背景 某环境客户部署了一个kubernetes集群 xff0c 发现flannel的pod一直重启 xff0c 始终处于CrashLoopBackOff状态 排查 对于始终CrashLoopBackOff的pod xff0c 一般是应用本身
  • k8s pod报错Process failed to launch spawn E2BIG

    一 问题描述 近期遇到k8s环境中一个pod无法正常启动 xff0c 启动报错 xff0c PM2 ERROR Process failed to launch spawn E2BIG 二 问题分析 2 1 了解报错相关知识 查阅资料发现
  • k8s 设置Node节点驱逐pod的时间

    官方api server参数具体作用 官方kube controller manager 参数具体作用 官方kubelet参数具体作用 官方kubelet参数具体作用 以下调整是需要加入到集群中的 xff0c 最后效果验证pod的迁移时间为
  • pod、container、sidecar

    pod是一个小家庭 xff0c 它把密不可分的家庭成员 container 聚在一起 xff0c Infra container则是家长 xff0c 掌管家中共通资源 xff0c 解决顺序和依赖关系 xff0c 家庭成员通过sidecar方
  • C++11之POD类型

    什么是POD类型 POD的全称叫做Plain Old Data xff0c 简单讲就是一个类或者一个结构体通过二进制拷贝之后还能保持其不变 xff0c 那么这个类型就是POD类型 什么类型属于POD类型 当一个类型具有平凡的定义和标准布局这
  • dyld: Library not loaded:

    dyld Library not loaded 问题 在使用阿里的开源库LazyScrollView的时候出现的这个问题 本地Xcode11 4 1 真机调试 dyld Library not loaded rpath LazyScroll
  • Mac环境下安装Pod

    Mac环境下安装Pod Mac环境下安装Pod 阿里云开发者社区 aliyun com 简介 Mac 环境下安装Pod Pod安装需要ruby ruby需要rvm可以终端中查看rvm 安装没有 如果没有安装则按以下步骤安装 rvm安装 cu
  • 本征正交分解(POD)入门(详解)

    思来想去还是把题目从 简介 改成了 入门 详解 其实详解主要就是针对可能没接触过矩阵论的同学 我也是研一才学的 入门是指的我会解释一些名词 方便理解 另外PCA 主成分分析 本质上就是POD 只是我最近翻的热工学论文大部分都用的POD这个名

随机推荐

  • gitlab-ce安装

    GitLab是一个利用 Ruby on Rails 开发的开源应用程序 xff0c 实现一个自托管的Git项目仓库 xff0c 可通过Web界面进行访问公开的或者私人项目 GitLab拥有与Github类似的功能 xff0c 能够浏览源代码
  • WSL2安装到其它目录下

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 WSL2是什么 xff1f 二 下载Ubuntu20 041 打开Mocrosoft Store2 导出发行版 总结 前
  • 解决Ubuntu20.04安装CUDA-11.2报256错误的问题

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 报错的原因是什么 xff1f 二 安装cuda 11 2三 安装nvidia driver 455四 再装cuda 11
  • ARM整形算力计算

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 RK3399规格 xff1f 二 开始计算1 参考2 计算 总结 前言 之前做人工智能使用RK3399的CPU去推理 x
  • WSL2使用USB设备

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 WSL2是什么 xff1f 二 编译内核1 查看自己的内核2 准备工作3 下载适合自己的内核版本4 开始编译4 使用内核
  • cron的正确食用方法

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 cron是什么 xff1f 二 使用步骤1 字段含义2 加强学习3 crontab命令4 工作原理5 其它用法6 补充内
  • windows 下 mongodb 导入导出collection(json、csv)

    1 下载mongodb xff0c 并安装 https www mongodb com dr fastdl mongodb org win32 mongodb win32 x86 64 2008plus ssl 3 4 0 signed m
  • 【WSL2启用systemd支持(一个配置即可)】

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 systemd是什么 xff1f 二 备份数据1 归档2 备份分支 三 准备工作1 内核升级 四 修改配置总结 前言 很
  • WSL2+Systemd支持度测试

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 systemd是什么 xff1f 二 开始测试1 Docker2 rsyslog3 systemd timesyncd4
  • 部分解决Ubuntu安装X11VNC需要自动登录的问题

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 GDM是什么 xff1f 二 VNC绑定GDM账户1 vnc绑定gdm登录 总结 前言 Ubuntu18 04 Ubun
  • Linux watchdog配置

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 watchdog是什么 xff1f 1 硬件看门狗2 软件看门狗 二 使用步骤1 硬件看门狗2 软件看门狗 总结 前言
  • Ubuntu内核打开硬件watchdog

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 watchdog是什么 xff1f 1 硬件看门狗2 软件件看门狗 二 编译内核1 添加配置2 开始编译3 安装内核4
  • explicit specialization of non-template

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 C 43 43 模板是什么 xff1f 二 错误原因1 主模板2 解决方法 总结 前言 相信很多人在使用C 43 43
  • HC-SR04超声波传感器使用

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 关于HC SR04二 使用步骤1 确保驱动已经安装2 安装GPIO工具3 安装GPIO的Python支持4 Python
  • 红外传感器使用

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 红外传感器 xff1f 二 使用步骤1 确保驱动已经安装2 安装GPIO工具3 安装GPIO的Python支持4 Pyt
  • Ubuntu20.04安装WineHQ-8.0

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 WineHQ是什么 xff1f 二 准备工作1 准备工作2 增加源密钥3 增加源地址 三 开始安装1 更新源缓存2 安装
  • Clion安装Platformio支持

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 系统配置二 什么是platformio三 安装配置1 安装Clion2 安装platformio插件3 安装platfo
  • ExecutorService 并发性能测试

    公共线程池 private ExecutorService executorService 61 Executors newFixedThreadPool 3 测试不使用线程池 xff0c 响应时间 public void test1 th
  • C++引用合并(引用的引用)

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 引用合并总结 前言 最近做一个项目 xff0c 遇到了C 43 43 的引用合并 xff0c 到底是怎么回事呢 xff1
  • C++ 普通旧数据解读(POD)

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 什么是普通旧数据 xff1f 二 使用步骤三 其他方法总结 前言 在开发C 43 43 的时候 xff0c 使用对象是绕