【C/C++】什么是POD(Plain Old Data)类型

2023年11月6日,周一下午


目录


POD类型的定义

  • 只包含标量类型(如整数、浮点数、指针等)或者其他 POD 类型的成员。
  • 没有用户自定义的构造函数、析构函数或拷贝控制成员
  • 没有虚函数或虚继承
  • 可以通过 memsetmemcpy 进行内存的简单复制和初始化。

这些标准在 C++03 标准中被定义。根据这个定义,POD 类型可以被视为简单的、平凡的数据类型,可以进行一些底层的操作,如内存复制、比较和序列化等。POD 类型通常用于与 C 语言进行交互、进行低级别的内存操作或进行数据序列化和传输。

标量类型

在计算机科学中,标量类型是指代表单个值的基本数据类型,它们表示的是一个简单的数值或者是一个指向内存中单个位置的指针。标量类型不需要进一步分解或组合,它们是最基本的数据类型,通常由编程语言提供原生支持。

在 C++ 中,以下是一些常见的标量类型:

  • 整数类型(如 int, char, short, long等)
  • 浮点数类型(如 float, double等)
  • 指针类型(如 int*, char*等)
  • 枚举类型(enum
  • 布尔类型(bool

标量类型可以直接进行算术运算、比较和赋值等操作,而不需要进一步的处理。相比之下,非标量类型(如数组、结构体、类等)可能由多个标量类型或其他非标量类型组成。

需要注意的是,标量类型通常不包括 C++ 的类类型(即用户自定义的类型),因为类类型可能包含成员函数、非标量类型的成员等。标量类型主要用于表示基本的单个数值或指针,它们在底层的内存表示和操作上相对简单。

POD类型的特点

  • 可以使用memset来清空
  • 可以使用memcpy来复制
  • 可以存储到文件中、也可以从文件中读取

POD类型的例子

当一个类型满足 POD(Plain Old Data)的定义时,它可以被认为是一个 POD 类型。

以下是一些常见的示例:

整数类型:

cpp 复制代码
int num;

这是一个简单的整数类型,只包含标量类型的成员,没有自定义的构造函数、析构函数或拷贝控制成员。

C 风格的结构体:

cpp 复制代码
struct Point {
    int x;
    int y;
};

这个结构体只包含两个整数成员,没有自定义的构造函数、析构函数或拷贝控制成员。

数组:

cpp 复制代码
int arr[10];

这是一个包含 10 个整数的数组,它只包含标量类型的成员。

C 风格的字符串:

cpp 复制代码
char str[20];

这是一个字符数组,可以用于存储字符串,也是一个 POD 类型。

std::array:

cpp 复制代码
array<int, 5> std_array = {1, 2, 3, 4, 5};

需要注意的是,C++ 的标准库提供的许多类型(例如 std::vectorstd::string)不属于 POD 类型,因为它们包含了额外的成员和复杂的行为。POD 类型主要用于与 C 语言进行交互,或者在需要进行底层内存操作的情况下使用。

使用 memcpy 对 POD 类型进行复制

cpp 复制代码
#include <cstring>
#include <iostream>

struct Point {
    int x;
    int y;
};

int main() {
    Point p1 = {10, 20};
    Point p2;
    
    // 使用 memcpy 复制 p1 的内存到 p2
    std::memcpy(&p2, &p1, sizeof(Point));
    
    // 检查复制结果
    std::cout << "p2.x: " << p2.x << std::endl;  // 输出 10
    std::cout << "p2.y: " << p2.y << std::endl;  // 输出 20
    
    return 0;
}

把POD类型存储到文件中,并从文件中再次读取

cpp 复制代码
#include <iostream>
#include <fstream>

struct Point {
    int x;
    int y;
};

int main() {
    Point p1 = {10, 20};
    Point p2;
    
    // 将 Point 对象存储到文件中
    std::ofstream outfile("point.bin", std::ios::binary);
    if (outfile.is_open()) {
        outfile.write(reinterpret_cast<char*>(&p1), sizeof(Point));
        outfile.close();
    }
    
    // 从文件中读取 Point 对象
    std::ifstream infile("point.bin", std::ios::binary);
    if (infile.is_open()) {
        infile.read(reinterpret_cast<char*>(&p2), sizeof(Point));
        infile.close();
    }
    
    // 检查读取结果
    std::cout << "p2.x: " << p2.x << std::endl;  // 输出 10
    std::cout << "p2.y: " << p2.y << std::endl;  // 输出 20
    
    return 0;
}

查看生成的二进制文件point.bin

相关推荐
郝学胜-神的一滴30 分钟前
Qt 入门 01-01:从零基础到商业级客户端实战
开发语言·c++·qt·程序人生·软件构建
测试员周周34 分钟前
【Appium 系列】第06节-页面对象实现 — LoginPage 实战
开发语言·前端·人工智能·python·功能测试·appium·测试用例
宏笋39 分钟前
C++ thread的detach()方法详解
c++
旖-旎44 分钟前
深搜练习(单词搜索)(12)
c++·算法·深度优先·力扣
摇滚侠1 小时前
@Autowired 和 @Resource 的区别
java·开发语言
Wy_编程1 小时前
go语言中的结构体
开发语言·后端·golang
SeaTunnel1 小时前
(八)收官篇 | 数据平台最后一公里:数据集成开发设计与上线治理实战
java·大数据·开发语言·白鲸开源
大卡片2 小时前
C++的基础知识点
开发语言·c++
米罗篮2 小时前
DSU并查集 & 拓展欧几里得-逆元
c++·经验分享·笔记·算法·青少年编程
谙弆悕博士2 小时前
【附C++源码】从零开始实现 2048 游戏
java·c++·游戏·源码·项目实战·2048