3

Bjarne Stroustrup:我的经验法则是,当且仅当您可以考虑类的不变量时,您应该拥有一个具有接口和隐藏表示的真实类。

在当前的项目中,我有一个名为 Widget 的基类。它具有用于 x、y、宽度、高度(基本上是一个 rect 数据结构)的私有变量以及每个变量的公共 getter 和 setter。除了成为一个愚蠢的变量持有者之外,他们对班级没有任何意义。根据上面 Bjarnes 的评论,我摆脱了这个类,但我想知道我应该如何与需要它们的子类共享这个数据结构。我应该将它们单独包含为每个班级的成员吗?将它们放在 Widget 命名空间中?

4

3 回答 3

2

您可以使用结构

例如

struct widget
{
    int x;
    int y;
    int w;
    int h;
};
于 2012-11-10T22:38:19.260 回答
1

我不确定我是否完全同意 Bjarne(除了不变量之外,更改表示的能力可能是一个重要的问题,尽管在这种情况下,甚至将实际定义移动到PImpl而不仅仅是制作它可能很重要private)。public但是,如果不担心更改的成员和/或不变量,您可以将变量分组到可以访问其成员的结构中。如果成员确实只是集中在一起而没有语义含义,您甚至可以只使用 a std::tuple

typedef std::tuple<int, int, double, double> widget;

...尽管在这种情况下,不同的成员确实具有访问功能-出于与不变量和前向兼容性无关的技术原因。

于 2012-11-10T22:46:04.430 回答
0

我认为您在那里严重误读了 Stroustrup,让我强调一下我认为重要的部分:

我的经验法则是,当且仅当您可以考虑该类的不变量时,您应该拥有一个具有接口和隐藏表示的真实类。

我相信他并不是在谈论在这种情况下不使用关键字class,而是指的是逻辑类(或“真实类”)。差异相当显着。一个类(注意没有降价)是一个具有自包含接口和可能隐藏实现的数据结构(参见 pimpl idiom)。这意味着,(逻辑)类的工作对用户是不可见的,并且类对象通过成员函数和自由函数进行通信。在数据抽象方面,有时被解释为“不要从外部访问成员变量”,但这只是核心思想的一个较浅的措辞。

您仍然应该像您所做的那样(或者像CommanderDietmar Kühl建议的那样)对异构数据集合使用结构化设计。用不使用classstruct关键字是个人喜好,但我倾向于使用struct关键字所以很明显这种类型不是逻辑意义上的类,而只是属于一起的一些数据。我发现使用适当的 struct 比 an 更可取,std::tuple因为您可以命名所有成员,赋予它们含义,而不是通过索引访问它们并且必须记住每个索引的含义。此外,struct将来修改和扩展 a 更容易。

于 2012-11-10T23:05:51.113 回答