C++ 复合数据类型简介

我们介绍了基本数据类型(fundamental data types),它们是 C++ 核心语言直接提供的最基础数据类别。

迄今为止,我们的程序大量使用这些基本类型,特别是 int。然而,随着需求变得复杂,仅靠基本类型已无法覆盖所有场景。

示例 1:分数运算

假设你正在编写一个用于计算两个分数乘积的数学程序。如何在程序中表示一个分数?你可能会使用一对整数——一个分子、一个分母:

#include <iostream>

int main()
{
    // 第一个分数
    int num1 {};
    int den1 {};

    // 第二个分数
    int num2 {};
    int den2 {};

    // 用于吃掉分子与分母之间的斜杠
    char ignore {};

    std::cout << "Enter a fraction: ";
    std::cin >> num1 >> ignore >> den1;

    std::cout << "Enter a fraction: ";
    std::cin >> num2 >> ignore >> den2;

    std::cout << "The two fractions multiplied: "
              << num1 * num2 << '/' << den1 * den2 << '\n';

    return 0;
}

示例运行:

Enter a fraction: 1/2
Enter a fraction: 3/4
The two fractions multiplied: 3/8

虽然程序能跑,但存在两个问题:

  1. 每对整数之间仅靠注释和上下文暗示其关联,耦合度低;
  2. 遵循 DRY(Don’t Repeat Yourself)原则时,应把输入分数封装成函数,但函数只能返回一个值,如何同时返回分子与分母?

示例 2:员工 ID 列表

若需保存 100 位员工的 ID,你可能会这样写:

int main()
{
    int id1 { 42 };
    int id2 { 57 };
    int id3 { 162 };
    // ……
}

但面对 100 名员工时,你需要输入 100 个变量名,打印或传参时更是一场灾难。显然,基本类型无法胜任规模扩展。

复合数据类型

好在 C++ 提供了复合数据类型(compound / composite data types):以现有类型为基础构造的新类型,具备额外属性与行为,专门解决此类问题。

关键要点

所有数据类型要么为基本类型,要么为复合类型。C++ 标准明确定义了每一类型所属类别。

本章及后续章节将展示如何利用复合类型优雅地解决上述难题。

C++ 支持的复合类型概览

  • 函数
  • C 风格数组
  • 指针类型
    ‑ 对象指针
    ‑ 函数指针
    ‑ 成员指针(数据成员 / 成员函数)
  • 引用类型
    ‑ 左值引用
    ‑ 右值引用
  • 枚举类型
    ‑ 非限定枚举
    ‑ 限定枚举
  • 类类型
    ‑ struct
    ‑ class
    ‑ union

你已频繁使用其中一种复合类型:函数。例如:

void doSomething(int x, double y)
{
}

其类型为 void(int, double),由基本类型组合而成,故为复合类型。函数还具备“可调用”等特殊行为。

鉴于内容繁多,我们将分章节展开:

  • 本章:左值引用、指针等较简单的复合类型;
  • 下一章:非限定/限定枚举及首个类类型——struct
  • 后续章节:深入类类型并介绍实用数组类型,包括 5.7 课将引入的 std::string(本质上也是类类型)。

术语

“类类型”统指 structclassunion,后续课程将频繁使用。

准备好了吗?让我们启程!

关注公众号,回复"cpp-tutorial"

可领取价值199元的C++学习资料

公众号二维码

扫描上方二维码或搜索"cpp-tutorial"