Изменить: я оставлю первую часть моего вопроса, как я первоначально разместил его, хотя теперь я вижу, что я плохо сформулировал вопросы в конце. Я всегда воспринимаю все чрезвычайно буквально, и иногда меня удивляет, что другие этого не делают. Я знаю, что это мой собственный недостаток. Я попытался перефразировать вопросы, чтобы, надеюсь, лучше рассказать, какие ответы я на самом деле искал.
Позвольте мне начать с того, что фактическая реализация этого, вероятно, не имеет большого значения, так как я работаю над очень мелким проектом, но я всегда высоко ценил теорию, чтобы выработать правильные привычки с самого начала, и поэтому я склонен застрять в местах, где это не имеет значения. Давайте представим, что это важно, хотя. Мне не терпится узнать плюсы и минусы различных вариантов, которые у меня есть в этой ситуации.
Я работаю над программой, в которой вы можете настроить среду по своему вкусу. Настройки для одной такой среды называются профиль. Вы можете переключаться между несколькими профилями, и только один профиль может быть активным одновременно.
Вполне возможно, что я захочу обновить программу в будущем, а это значит, что я могу попытаться загрузить устаревший формат профиля, в котором отсутствуют определенные настройки. Чтобы упростить себе задачу и обеспечить обратную совместимость, я решил создать класс под названием 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;
};
Первая версия проста, и я уверен, что она лучше по производительности и использованию памяти, чем вторая и третья версии (если есть какая-либо разница). Однако имена могут быть очень длинными, и я не фанат длинных идентификаторов.
Во второй версии я могу использовать намного более короткие идентификаторы, и я действительно предпочел бы идентифицировать свойство, используя profile.color_palette.pos.x
чем profile.color_palette_pos_x
, Однако есть один недостаток. Когда я печатаю profile.
это предполагает window
который не является свойством, но структурой, и я не могу это использовать, когда я не работаю непосредственно внутри profile.h
,
Третья версия решает проблемы, которые у меня возникают с первой и второй версиями, но представляет новую проблему. Когда я печатаю profile.
это предполагает some_setting
который я не смогу получить доступ через profile
только через profile.general_settings
, Это просто странные Code :: Blocks или есть что-то фундаментальное, о чем я просто не знаю?
Так что мои вопросы (перефразировать):
LikeThis
и геттеры и сеттеры обычно называют like_this
)? Должен ли я объявить их внутри или за пределами области, в которой я намерен их использовать? Я читал, что люди обычно советуют против более широкой области, чем необходимо, и я просто прошу убедиться, потому что я никогда прежде не работал в среде, где занятия внутри классов целесообразны или даже законны.
- В этом сценарии существует ли структура, которая объективно предпочтительнее других? (это может быть что-то, о чем я даже не думал)
Нет, это полностью зависит от ваших реальных вариантов использования, и что подойдет лучше для их решения
- Вложенные структуры (по крайней мере, вложенные структуры декларацииКажется, они создают больше проблем, чем решают, и они резко снижают читабельность, поэтому моя интуиция говорит мне, что мне следует избегать этого. Каково общее согласие по этому вопросу?
Вложенные структуры имеют свои варианты использования сами по себе, в большинстве случаев, если вложенная структура / класс тесно связана с объявленным внешним классом / структурой (то есть, как стандартные классы итераторов контейнера связаны с их соответствующими реализациями контейнера). Использование их без такой тесной связи, это усложнит, да.
- Если я использую вложенные структуры, я должен использовать соглашения об именах для структур или для переменных? Должен ли я объявить их внутри или за пределами области, в которой я намерен их использовать?
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_)
{}
};