关于等级结构的一般建议

时间:2014-06-27 23:12:48

标签: c++ data-structures struct nested hierarchical

编辑:我将离开我最初发布的问题的第一部分,尽管我现在可以看到我在最后说的问题很糟糕。我总是非常直接地把所有东西都拿走,而有时候其他人却不会感到惊讶。我知道这是我自己的缺点。我试图重新解释这些问题,希望能更好地传达我实际需要的答案。

首先我要说的是,实际实施这一点可能并不重要,因为我正在开展一个非常小规模的项目,但我总是高度重视理论,以便我从中养成正确的习惯。开始,因此我倾向于陷入无关紧要的地方。但是,让我们假装它很重要。我很想知道在这种情况下我有不同选择的利弊。

我正在开发一个程序,您可以根据自己的喜好自定义环境。一个此类环境的设置称为配置文件。您可以在多个配置文件之间切换,并且一次只能激活一个配置文件。

我可能希望将来更新程序,这意味着我可能会尝试加载过时的配置文件格式,而某些设置缺失。为了使自己更容易并确保向后兼容性,我决定创建一个名为ProfileManager的类,它将加载配置文件格式并在必要时更新它们。

我还决定制作一个struct Profile来保存所有设置,这就是我的问题所在。

请参阅我在此尝试过的三个版本:

struct Profile
{
    // Version one: lots of variables with closely related names
    bool window_one_open;
    bool window_one_collapsed;
    int window_one_pos_x;
    int window_one_pos_y;
    int window_one_width;
    int window_one_height;

    // Version two: named structs used to easily create multiple entries of the same format
    struct position
    {
        int x;
        int y;
    };

    struct window
    {
        bool open;
        bool collapsed;
        position pos;
        int width;
        int height;
    };

    window color_palette;
    window text_editor;
    window browser;

    // Version three: unnamed struct(s) used to simply group certain variables together
    struct
    {
        bool some_setting;
        bool some_other_setting;
        int important_number;
    } general_settings;
};

版本1很简单,我确信它在性能和内存使用方面的得分比第二版和第三版要好(如果有任何差异,那就是)。但是名字可能会很长,而且我不喜欢长标识符。

在第二版中,我可以使用更短的标识符,而我真的更愿意使用profile.color_palette.pos.x而不是profile.color_palette_pos_x来识别属性。但是有一个缺点。当我输入profile.时,它会建议window这不是属性而是结构,当我不直接在profile.h内部工作时,我没有用它。

第三版解决了我对第一版和第二版的问题,但它引入了一个新问题。当我输入profile.时,它会建议some_setting我无法通过profile访问profile.general_settings,而只能通过LikeThis。这只是Code :: Blocks很奇怪还是有一些我根本不知道的基本内容?

所以我的问题是(改写):

  • 使用我的任何样本结构会是客观错误的选择吗?也就是说,他们中的任何一个是否比其他表现更差?与版本1相比,嵌套结构是否使用了过多的内存?是否有任何版本比其他版本更容易出错?我只是在这里寻找是或否的答案,以便我知道与他们中的任何一个一起去我是不明智的。或许,在决定要使用的结构时,我应该记住一些其他内容吗?
  • 在决定是否使用嵌套结构时,是否有任何不成文的规则或一些常识?再一次,我只是在寻找一个是或否。
  • 是否存在人们希望我用于嵌套结构的命名约定(类似于like_this,getter和setter通常命名为{{1}})?我应该在我打算使用它们的范围之内还是之外声明它们?我读过,人们通常建议的范围超出必要的范围,我只是要求确定,因为我之前从未在一个环境中工作过,课堂内的课程是可取的,甚至是合法的。

1 个答案:

答案 0 :(得分:1)

  
      
  • 在这种情况下,是否存在客观上优于其他结构的结构? (这可能是我想不到的东西)
  •   

不,这完全取决于您的实际使用情况,以及更适合解决它们的问题

  
      
  • 嵌套结构(至少是嵌套的struct 声明)似乎引入了比他们解决的更多问题,并且它们大大降低了可读性,所以我的直觉告诉我应该避免它。对此有何普遍共识?
  •   

嵌套结构本身具有它们的用例,大多数情况下,如果嵌套的结构/类与声明的外部类/结构紧密耦合(即标准容器迭代器类与其关联的容器实现耦合)。在没有这种紧密耦合关系的情况下使用它们会使事情变得复杂,是的。

  
      
  • 如果我使用嵌套结构,我应该使用结构或变量的命名约定吗?我应该在我打算使用它们的范围之内还是之外声明它们?
  •   

AFAIK没有特殊的命名约定,除了你想要与C ++标准类兼容之外'模板参数。如果您有类似嵌套的iterator类定义,请将其命名并按照标准算法和其他操作的要求履行合同。

正如您在示例#2中所发现的那样,似乎接口(在您的类外声明)可能更适合组合您需要的关系和抽象

struct IPosition {
    virtual int x() const = 0;
    virtual int y() const = 0;

    virtual ~IPosition() {}
};

struct IWindow {
    virtual bool open() const = 0;
    virtual bool collapsed() const = 0;
    virtual const IPosition& pos() const = 0;
    virtual int width() const = 0;
    virtual int height() const = 0;

    virtual ~IWindow() {}
};

struct Profile {
    IWindow& windowOne;
    IWindow& windowTwo;

    // Provide an appropriate IWindow implementation instances 
    // when constructing here
    Profile(IWindow& windowOne_, IWindow& windowTwo_) 
    : windowOne(windowOne_)
    , windowTwo(windowTwo_)
    {}
};