且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-06-27 02:40:56

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

I think there are two important design principles to consider here:

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

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

A class has an invariant when there is such thing as an invalid state for that class. The class should maintain its invariant at all times.

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

Consider a Point type that represents a 2D geometric point. This should just be a struct with public x and y data members. There is no such thing as an invalid point. Every combination of x and y values is perfectly fine.

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

In the case of a Person, whether it has invariants depends entirely on the problem at hand. Do you consider such things as an empty name as a valid name? Can the Person have any date of birth? For your case, I think the answer is yes and your class should keep the members public.

参见:类应该强制执行不变量

非友元非成员函数改进封装.

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

There's no reason your age function should be implemented as a member function. The result of age can be calculated using the public interface of Person, so it has no reason to be a member function. Place it in the same namespace as Person so that it is found by argument-dependent lookup. Functions found by ADL are part of the interface of that class; they just don't have access to private data.

如果您确实将其设为成员函数,并且有一天向Person 引入了一些私有状态,那么您将拥有不必要的依赖项.突然 age 获得了比它需要的更多的数据访问权限.

If you did make it a member function and one day introduced some private state to Person, you would have an unnecessary dependency. Suddenly age has more access to data than it needs.

参见:非成员函数如何改进封装p>

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

So here's how I would implement it:

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

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