在C ++中构造类的最佳方法

时间:2015-01-16 08:22:48

标签: c++ class

很长一段时间以来,我一直在考虑遵循类结构的方方面面。让我们看看我们有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和其他副本。

你怎么看?你使用哪种结构?为什么?

2 个答案:

答案 0 :(得分:2)

选项1

优点Style对象的部分封装
缺点:您必须在Font中为Style中的每个字段提供一种方法。这可能适用于这样的简单应用程序,但是想象一下,Paragraph类会有FontContent个字段(或者更多)。然后你必须使用选项2或再次重写Font中的所有方法。

选项2

优点:您可以从任何级别的层级完全访问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也没问题。