C++ 中的结构体和类(Structs vs. Classes)

发布于:2025-03-16 ⋅ 阅读:(24) ⋅ 点赞:(0)

好的,以下是根据你提供的内容对 C++ 中结构体(struct)和类(class)的讲解。


C++ 中的结构体和类(Structs vs. Classes)

在 C++ 中,structclass 都是用于定义用户自定义数据类型的关键字。它们在语法上几乎等同,都可以包含数据成员和成员函数。然而,在实际开发中,我们通常会为它们赋予不同的语义,以便在定义数据类型时合理选择使用 struct 还是 class。以下是具体的讲解:

1. 基本区别:默认访问权限
  • struct:默认访问权限是 public。如果未指定访问修饰符,struct 中的成员(包括数据成员和成员函数)在外部是可直接访问的。
  • class:默认访问权限是 private。如果未指定访问修饰符,class 中的成员在外部无法直接访问,必须通过公共接口(如成员函数)来操作。

除了默认访问权限的区别,structclass 在功能上是等价的。但我们通过人为约定为它们添加了不同的使用场景。


2. 使用约定:struct vs. class

根据你提供的内容,以下是选择 structclass 的建议:

  • 仅当只有数据时使用 struct
    如果一个数据类型仅仅是数据的集合(即“消极对象”,passive objects),没有额外的行为或成员函数,则应使用 struct 定义。

    • 这种情况下,struct 通常只包含数据成员,可能还包括一些关联的常量(如枚举值或静态常量)。
    • 数据访问通过直接访问成员实现,不需要定义额外的存取函数(如 getter 或 setter)。
    • 允许的成员函数仅限于处理数据成员的基本函数,例如构造函数、析构函数、Initialize()Reset()Validate(),而不涉及更复杂的行为。
    • 示例
      struct Point {
          int x;
          int y;
          Point(int x_ = 0, int y_ = 0) : x(x_), y(y_) {}
      };
      // 外部直接访问
      Point p;
      p.x = 10;
      p.y = 20;
      
  • 其他情况一概使用 class
    如果数据类型需要更多的函数功能来操作数据,或者需要控制对数据的访问(即封装),则应使用 class 定义。

    • class 更适合需要复杂行为或数据隐藏的场景,通常通过 private 数据成员和 public 成员函数来实现。
    • 如果不确定使用哪一个,直接选择 class 是更安全和通用的做法。
    • 示例
      class Rectangle {
      private:
          int width;
          int height;
      public:
          Rectangle(int w = 0, int h = 0) : width(w), height(h) {}
          int getArea() const { return width * height; }
          void setWidth(int w) { width = w; }
      };
      // 外部通过函数访问
      Rectangle r;
      r.setWidth(5);
      

这种约定使得代码更具可读性和可维护性:看到 struct 时,开发者可以预期它是一个简单的数据容器;看到 class 时,则可能涉及封装和复杂行为。


3. 与 STL 结合的特殊情况

在 C++ 标准模板库(STL)中,某些场景下可以优先使用 struct 而不是 class

  • 仿函数(functors)
    仿函数是定义了 operator() 的对象,通常用于 STL 算法中。由于仿函数主要是提供行为而非存储状态,使用 struct 可以更简洁地表达其用途。

    • 示例
      struct Compare {
          bool operator()(int a, int b) const { return a < b; }
      };
      std::sort(v.begin(), v.end(), Compare());
      
  • 特性(traits)
    特性是用于描述类型属性的模板技术,通常只包含类型定义或静态成员,而不涉及数据封装,因此也适合使用 struct

    • 示例
      struct IsIntegral {
          static const bool value = true;
      };
      

在这些情况下,struct 的默认 public 访问权限更符合其无状态或简单定义的特性。


4. 命名规则的差异

你提供的内容中提到,structclass 的成员变量可能使用不同的命名规则。这是因为:

  • struct 的成员:由于通常是 public 的,可以直接访问,因此命名可以更简单直接,例如 xy
  • class 的成员:由于通常是 private 的,需要通过 getter 和 setter 访问,命名时可能需要考虑与访问函数的协调,例如使用前缀或下划线(如 m_width_width)以区分私有成员。

这种命名差异是编码规范的一部分,具体规则取决于项目或团队的风格。


5. 总结
  • struct
    • 适用于仅有数据成员的简单数据容器。
    • 默认 public 访问权限。
    • 适合消极对象,可能包含基本构造函数等,但不涉及复杂行为。
    • 在 STL 中可用于仿函数和特性。
  • class
    • 适用于需要封装数据和行为的数据类型。
    • 默认 private 访问权限。
    • 如果不确定,直接使用 class

通过遵循这些约定,我们可以让 C++ 代码更清晰地表达设计意图,提升代码的可读性和可维护性。如果你有更多问题,欢迎随时提问!


希望这个讲解对你有帮助!