Общие советы по иерархическим структурам

Изменить: я оставлю первую часть моего вопроса, как я первоначально разместил его, хотя теперь я вижу, что я плохо сформулировал вопросы в конце. Я всегда воспринимаю все чрезвычайно буквально, и иногда меня удивляет, что другие этого не делают. Я знаю, что это мой собственный недостаток. Я попытался перефразировать вопросы, чтобы, надеюсь, лучше рассказать, какие ответы я на самом деле искал.

Позвольте мне начать с того, что фактическая реализация этого, вероятно, не имеет большого значения, так как я работаю над очень мелким проектом, но я всегда высоко ценил теорию, чтобы выработать правильные привычки с самого начала, и поэтому я склонен застрять в местах, где это не имеет значения. Давайте представим, что это важно, хотя. Мне не терпится узнать плюсы и минусы различных вариантов, которые у меня есть в этой ситуации.

Я работаю над программой, в которой вы можете настроить среду по своему вкусу. Настройки для одной такой среды называются профиль. Вы можете переключаться между несколькими профилями, и только один профиль может быть активным одновременно.

Вполне возможно, что я захочу обновить программу в будущем, а это значит, что я могу попытаться загрузить устаревший формат профиля, в котором отсутствуют определенные настройки. Чтобы упростить себе задачу и обеспечить обратную совместимость, я решил создать класс под названием 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)? Должен ли я объявить их внутри или за пределами области, в которой я намерен их использовать? Я читал, что люди обычно советуют против более широкой области, чем необходимо, и я просто прошу убедиться, потому что я никогда прежде не работал в среде, где занятия внутри классов целесообразны или даже законны.

1

Решение

  • В этом сценарии существует ли структура, которая объективно предпочтительнее других? (это может быть что-то, о чем я даже не думал)

Нет, это полностью зависит от ваших реальных вариантов использования, и что подойдет лучше для их решения

  • Вложенные структуры (по крайней мере, вложенные структуры декларацииКажется, они создают больше проблем, чем решают, и они резко снижают читабельность, поэтому моя интуиция говорит мне, что мне следует избегать этого. Каково общее согласие по этому вопросу?

Вложенные структуры имеют свои варианты использования сами по себе, в большинстве случаев, если вложенная структура / класс тесно связана с объявленным внешним классом / структурой (то есть, как стандартные классы итераторов контейнера связаны с их соответствующими реализациями контейнера). Использование их без такой тесной связи, это усложнит, да.

  • Если я использую вложенные структуры, я должен использовать соглашения об именах для структур или для переменных? Должен ли я объявить их внутри или за пределами области, в которой я намерен их использовать?

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_)
{}
};
1

Другие решения


По вопросам рекламы [email protected]