很长一段时间以来,我一直在考虑遵循类结构的方方面面。让我们看看我们有Style类,它存储字体大小,字体颜色和其他字体样式设置。我们还有一个Font类。 现在我们有两种方法来描述我们的任务。第一个是:
class Style {
public:
unsigned short size;
unsigned short color; // just for example
};
class Font{
private:
Style style;
public:
void setSize( unsigned short fontSize ) {
this->style.size = fontSize;
}
void setColor( unsigned short fontColor ) {
this->style.color = fontColor;
}
void setStyle( Style style ) {
this->style = style;
}
};
第二个是:
class Style {
private:
unsigned short size;
unsigned short color; // just for example
public:
void setSize( unsigned short fontSize ) {
this->style.size = fontSize;
}
void setColor( unsigned short fontColor ) {
this->style.color = fontColor;
}
};
class Font{
private:
Style style;
public:
void setStyle( Style style ) {
this->style = style;
}
};
我经常在我的应用中使用Style-object:
Style style;
style.size = 10;
style.color = 02034023; // doesn't matter :)
font.setStyle( style );
因此,如果我们在Style类中定义setColor,setFont和其他空格,我们将它们全部加载到我们的内存中(由Style-object的每个副本)。如果我们在Font类中定义setColor和其他类,我们只有一个在内存中加载的setColor副本。因为我经常使用Style对象的创建,所以我不想在内存中加载setColor和其他内容,只是为了有机会使用这样的类:style.setSize( 10 );
。使用这种技术,我只在内存中加载一个setSize和其他副本。
你怎么看?你使用哪种结构?为什么?
答案 0 :(得分:2)
优点:Style
对象的部分封装
缺点:您必须在Font
中为Style
中的每个字段提供一种方法。这可能适用于这样的简单应用程序,但是想象一下,Paragraph
类会有Font
和Content
个字段(或者更多)。然后你必须使用选项2或再次重写Font
中的所有方法。
优点:您可以从任何级别的层级完全访问Style
对象
缺点:每次要更改某些内容时,都必须实例化一个新对象。对象生命周期/所有权出现问题。(我是否删除此处的样式?是否在其他地方引用?)。 Style对象没有封装。
对getter使用const-correctness:
class Style
{
public:
unsigned short size;
unsigned short color; // just for example
};
class Font
{
private:
Style style;
public:
const Style& GetStyle() const { return style; }
Style& GetStyle() { return style; }
};
通过这种方式,您可以清楚地说明Style
对象的所有权属于Font
,同时也可以在给定的位置读取/更改它,即
font.GetStyle().size = 14;
此外,您可以使用功能签名来清楚地说明内部Font
发生的帽子。
void AccessFont(const Font& font)
{
unsigned size = font.GetStyle().size; // works
font.GetStyle().size = 16; // doesn't compile
}
同样,如果你来到一个带有Paragraph
类的层次结构,你只需添加Font
字段的两个getter。然后,您可以传递Paragraph
的常量和非常量版本。
答案 1 :(得分:0)
我认为两者都没问题。
如果您打算使用选项1,我建议您不要提供setStyle
方法,以便Style
完全封装。这样,Font
的客户甚至不需要知道Font
包含Style
个对象。 Style
中的更改仅影响Font
,您甚至可以在不破坏客户端的情况下将Font
的实施更改为以后不使用Style
对象。
如果Style
不太可能改变,并且只是一个小的对象,你将按价值传递,那么我认为选项2也没问题。