具有成员函数的 C++ 结构与具有公共(public)变量的类

标签 c++ class struct

这确实是一个良好形式/最佳实践的问题。我使用 C++ 中的结构来形成旨在基本上保存数据的对象,而不是创建一个具有大量访问器方法的类,这些方法除了获取/设置值之外什么都不做。例如:

struct Person {
    std::string name;
    DateObject dob;
    (...)
};

如果您想象那里还有 20 个变量,那么将它写成一个包含私有(private)成员和 40 多个访问器的类会很麻烦,而且对我来说似乎很浪费。

但有时,我可能还需要为数据添加某种最小功能。在示例中,假设我有时还需要年龄,基于 dob:

struct Person {
    std::string name;
    DateObject dob;
    (...)
    int age() {return calculated age from dob;}
}

当然,对于任何复杂的功能,我都会创建一个类,但是对于像这样的简单功能,这是“糟糕的设计”吗?如果我确实使用了一个类,将数据变量保留为公共(public)类成员是一种不好的形式,还是我只需要接受它并使用一堆访问器方法创建类?我了解类和结构之间的区别,我只是在询问最佳实践。

最佳答案

我认为这里有两个重要的设计原则需要考虑:

  1. 如果该类有一些不变量,则通过接口(interface)隐藏该类的表示。

    当该类存在无效状态时,该类具有不变量。该类应始终保持其不变性。

    考虑一个表示 2D 几何点的 Point 类型。这应该只是一个具有公共(public) xy 数据成员的 struct。没有无效点之类的东西。 xy 值的每个组合都非常好。

    对于Person,它是否具有不变量完全取决于手头的问题。您认为空名称之类的东西是有效名称吗? Person 可以有任何出生日期吗?对于您的情况,我认为答案是肯定的,您的类(class)应该公开成员。

    见:Classes Should Enforce Invariants

  2. 非友元非成员函数改进了封装性。

    没有理由将您的 age 函数实现为成员函数。 age的结果可以通过Person的公共(public)接口(interface)计算出来,所以没有理由成为成员函数。将它放在与 Person 相同的命名空间中,以便通过参数相关查找找到它。 ADL 找到的函数是该类接口(interface)的一部分;他们只是无权访问私有(private)数据。

    如果你确实让它成为一个成员函数,并且有一天向 Person 引入了一些私有(private)状态,你就会有一个不必要的依赖。突然间,age 对数据的访问权超出了它的需要。

    见:How Non-Member Functions Improve Encapsulation

所以我将如何实现它:

struct Person {
  std::string name;
  DateObject dob;
};

int age(const Person& person) {
  return calculated age from person.dob;
}

关于具有成员函数的 C++ 结构与具有公共(public)变量的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15572665/

相关文章:

c++ - 动态内存分配故障恢复

Python 类和命名空间?

java - 使用不同的包名在java中动态加载一个类

用C创建客户端时出现编译错误

c - 无法正确地将十六进制字节打包到无符号字符数组或指针中

c - 消失的二叉树

c++ - 转换运算符模板特化

c++ - 仅使用 get 或 set 的原始类型的线程安全威胁是否被夸大了?

c++ - 如何使用 boost MPI 出现死锁情况(我使用 MPICH 编译器)?

java - “找不到或加载主类”是什么意思?