类由其他更大的类组成的问题

时间:2009-11-19 15:46:51

标签: c++ design-patterns

想象一下,你有一个包含几十个私有成员变量的类。每个成员变量都有一个公共getter和一个setter函数:

class Foo
{
public:
   int GetA() const { return m_a; }
        :
   int GetZ() const { return m_z; }

   void SetA(int val) { m_a = val; }
        :
   void SetZ(int val) { m_z = val; }

private:
   int m_a;
        :
   int m_z
};

现在我们有了第二个类,它由Foo(以及其他)组成:

class Bar
{
private:
   // some instances of other classes of about the same complexity as Foo
   Foo m_foo;
};

因此,Bar本质上是一个将单个实体中其他类的实例绑定在一起的类。

传递Bar实例的函数将要访问m_foo,以便它们可以调用其getter和setter函数。考虑到Scott Meyers在Effective C ++(第3版 - 第28项)中的建议,我不愿意添加一些东西,这些东西会向m_foo返回一个'句柄',例如。

Foo& GetFoo() const { return m_foo; }   // dubious const, I know

除了在Bar中复制每一个getter和setter之外,我还有其他选择吗?

我正在使用一些遗留代码,这些代码很懒,可以让'm_foo'公开!但这违背了斯科特的其他一些建议(在这种情况下,第22项 - “声明数据成员私有”)。

出于这种约束的方式吗?

4 个答案:

答案 0 :(得分:2)

您应该将数据成员公开。

无论如何,它已经在概念上是公开的,如果你给你描述的Bar getters和setter。这同样适用于getter返回引用的任何getter / setter对。 (除了你可以包括前/后挂钩,但这是一个单独的问题而不是封装。)

答案 1 :(得分:0)

如果你现在无论如何都有getter和setter这样的大类,我认为返回对该对象的引用并不是一个问题,毕竟在它们之间还有一层 - 你基本上仍然可以控制所设置的内容/进入Foo。

OTOH也许如果你设计的课程有很多公共属性,也许你应该重新考虑你的设计,课堂上的东西越多越笨重。

编辑:也许您可以更改公共成员的数据结构并将其放在某种地图中?这样它至少可以节省一些写作。 : - )

get("propertyname")
set("propertyname",value)

答案 2 :(得分:0)

  

想象一下,你有一个包含几十个私有成员变量的类。每个成员变量都有一个公共getter和一个setter函数。

嗯,我不愿意。阅读here为什么这是一个坏主意。

答案 3 :(得分:0)

不是,不。您可以为foo中的每个getter或setter创建转发getter和setter。你可以将foo实例公开,或者你可以为foo创建一个getter和setter。

一般来说,我发现,面对这种情况时,最好重新审视我在foo和bar中封装数据的原因。通常我会发现可以将foo分成多个类,然后将需要访问foo数据的每个部分的函数作为方法移动到适当的类中。这导致变量实际上是其类的私有成员变量,并且不需要setter和getter。这就是面向对象编程应该如何工作的方式。

有关对遗留代码执行此操作的良好指南,请查看Martin Fowler的重构