所以我花了一些时间考虑这个问题并且一直在谷歌寻找'解决方案'(解决方案很可能是一个偏好的问题,但我不确定这一点)。以下是我遇到的问题,但问题可以应用于很多关于构图的情况。
我有一个类Color,包含红色,绿色,蓝色和alpha的成员。其中每个都有一个set和get成员函数。很简单。
class Colour
{
public:
float getRed();
void setRed(float);
float getGreen();
void setGreen(float);
...
private:
float red;
float green;
...
};
我将在其他类中使用此类来指示它们的颜色,例如(省略构造函数和析构函数):
class ColourableObject
{
private:
Colour colour;
};
现在我的问题是:这个ColourableObject类如何最好地访问这个Color对象?是否最好直接检索Color对象以访问其成员函数,如下所示:
class ColourableObject
{
public:
Colour& getColour();
private:
Colour colour;
};
或者,最好是将ColourableObject类赋予其自己的set并获取color的函数,其中对Color对象执行操作,如下所示:
class ColourableObject
{
public:
float getRed();
void setRed(float);
...
private:
Colour colour;
};
对我而言,前者是最合乎逻辑的,因为通过简单地直接对此Color对象进行操作,为每个需要此Color对象的类添加功能会省去很多麻烦。
但是,后者是否更容易更改ColourableObject类?更不用说colourableObject.getColour()。setRed(x)对我来说似乎不太自然,因为get和set相互冲突。
我可能完全采用了错误的方法。我对C ++比较陌生,所以我愿意学习!所以问题是,我应该使用前一种方法,后一种方法,还是一种完全不同的方法?
答案 0 :(得分:3)
不要直接回答你的问题,但我会摆脱所有的设置者(在任何情况下通常都是一个不好的标志,并使用构造函数):
Color c = Color( 123, 17, 77 );
其中三个构造函数参数是RGB值。
答案 1 :(得分:1)
我可能会重新创建你的课程,以防你需要添加其他颜色,如Orange,Purple,Cyan或Crayola的新Smooky Applewood!
类似于基色类,并通过引入新颜色对该基类起作用。 这样,你正在处理哪种颜色并不重要。这都是一个黑盒子。这也将回答你的第二个问题,因为它不需要重新定义你的setColor和getColor名称方法。他们不需要知道或关心你指的是什么颜色。
我觉得Code Complete(这本书)有一个部分对于看到有太多get / set方法的类有点小问题。它通常归结为错误的做法。
答案 2 :(得分:1)
在这种情况下,你使用getter和setter并没有多大意义。您也可以让float
成员Colour
公开。除非您需要对多个私有成员进行验证或操作,否则请继续公开,并创建一个构造函数来适当初始化Colour
。
关于ColourableObject
,您应该问的问题是:其他不相关的类是否需要访问对象的Colour
成员?他们是否需要对其进行更改?如果那些 的答案是“不”,我会说你根本不应该对那个对象有任何吸气剂或设定器。否则,除非您需要进行验证或其他状态更改,否则只需将Colour
公开。
答案 3 :(得分:1)
DRY principle支持您的第一个选项,提供对Colour
对象的访问权限。
此外,您可能希望更改
Colour& getColour();
到
const Colour& getColour();
void setColour( const Colour& );
...因为这将确保您的ColourableObject
始终知道其颜色何时发生变化。
答案 4 :(得分:1)
最终,答案取决于您(或不希望)如何限制对嵌入Color对象的访问。
在你的第一选择中......
class ColourableObject
{
public:
Colour& getColour();
private:
Colour colour;
};
...你根本就没有限制访问权限。如果用户可以通过getColour()
访问私人会员,那么将其设为私有的重点是什么?您也可以跳过中间步骤,然后执行此操作:
class ColourableObject
{
public:
Colour colour;
};
当这样做时,一个人可以直接引用数据成员及其所有函数,例如C.colour.getRed();
(假设C是ColourableObject)
现在,假设你想以某种方式限制最终用户 - 他不能设置绿色或蓝色,但你可以让他设置红色。在这种情况下,您可能想要使用第二种选择:
class ColourableObject
{
public:
float getRed();
void setRed(float);
...
private:
Colour colour;
};
这是因为ColourableObject
的用户只能访问您的公共功能,而不能访问基础私有成员。如果您希望在最终用户和颜色选择之间有一些中间步骤,这个基本原理也适用。例如,以下内容:
class ColourableObject
{
public:
void setMood(enum Mood);
private:
Colour colour;
};
void ColourableObject::setMood(enum Mood)
{
if(Mood == HAPPY) colour.setRed(3);
if(Mood == SAD) colour.setBlue(11);
...
}
最后,您可以执行混合操作,使colour
数据成员保持公开状态,但也会为该数据成员添加其他访问者。
<强>要点:强>
第一种方法:
第二种方法:
答案 5 :(得分:0)
就个人而言,在Colorable成员的情况下,我更倾向于放弃“获取”部分:
colorableObject.Color().setRed(1.0f);
正如你所说,这完全是个人偏好(就像拼写一样!:)但是这样,对我来说它看起来像是一个“属性”,而不是一个getter / setter方法。