编辑:我将离开我最初发布的问题的第一部分,尽管我现在可以看到我在最后说的问题很糟糕。我总是非常直接地把所有东西都拿走,而有时候其他人却不会感到惊讶。我知道这是我自己的缺点。我试图重新解释这些问题,希望能更好地传达我实际需要的答案。
首先我要说的是,实际实施这一点可能并不重要,因为我正在开展一个非常小规模的项目,但我总是高度重视理论,以便我从中养成正确的习惯。开始,因此我倾向于陷入无关紧要的地方。但是,让我们假装它很重要。我很想知道在这种情况下我有不同选择的利弊。
我正在开发一个程序,您可以根据自己的喜好自定义环境。一个此类环境的设置称为配置文件。您可以在多个配置文件之间切换,并且一次只能激活一个配置文件。
我可能希望将来更新程序,这意味着我可能会尝试加载过时的配置文件格式,而某些设置缺失。为了使自己更容易并确保向后兼容性,我决定创建一个名为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很奇怪还是有一些我根本不知道的基本内容?
所以我的问题是(改写):
like_this
,getter和setter通常命名为{{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_)
{}
};