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

amn*_*sia 26 c++ struct class

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

struct Person {
    std::string name;
    DateObject dob;
    (...)
};
Run Code Online (Sandbox Code Playgroud)

如果你想象那里有20个变量,把它写成一个有私人成员和40多个访问者的类是很难管理的,对我来说似乎很浪费.

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

struct Person {
    std::string name;
    DateObject dob;
    (...)
    int age() {return calculated age from dob;}
}
Run Code Online (Sandbox Code Playgroud)

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

Jos*_*eld 24

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

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

    当存在该类的无效状态时,类具有不变量.班级应始终保持不变.

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

    在a的情况下Person,它是否具有不变量完全取决于手头的问题.您是否将空名称视为有效名称?可以Person有任何出生日期吗?对于你的情况,我认为答案是肯定的,你的班级应该让成员公开.

    请参阅:类应该强制实施不变量

  2. 非朋友非成员函数改进了封装.

    没有理由将您的age函数实现为成员函数.结果age可以使用公共接口计算Person,因此没有理由成为成员函数.将它放在相同的命名空间中,Person以便通过参数依赖查找找到它.ADL找到的函数是该类接口的一部分; 他们只是无法访问私人数据.

    如果你确实使它成为一个成员函数,并且有一天将一些私有状态引入Person,那么你将有一个不必要的依赖.突然间,他们age可以访问超出需求的数据.

    请参阅:非成员函数如何改进封装

所以这是我将如何实现它:

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

int age(const Person& person) {
  return calculated age from person.dob;
}
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案,以及我正在寻找的信息类型,谢谢! (2认同)

Pol*_*lar 6

在C++中,Structs是类,唯一的区别(至少我可以想到)是Structs中的成员默认是公共的,但在类中它们是私有的.这意味着使用Structs是完全可以接受的 - 本文解释得很好.