Я довольно новичок в программировании на C++ и объектно-ориентированном программировании, и у меня есть некоторые проблемы с правильным проектированием моих классов. Мое приложение основано на наборе параметров, которые пользователь может установить в файле конфигурации. Эти параметры считываются в начале выполнения и распределяются по разным частям программы, т. е. на основе этих параметров строятся классы, выполняющие разные задачи. Но похоже на этот вопрос
Элегантный способ передачи нескольких аргументов в функцию
возможно, какой-то класс зависит от множества различных параметров/опций (например, 9). Эти параметры могут указывать сам класс или выполнение общедоступных функций-членов. Эти опции/параметры не должны изменяться во время выполнения. Я думал о разных решениях для встраивания всех параметров в соответствующий класс таким образом, чтобы избежать уродливых вызовов функций/конструкторов, но ни одно из них не кажется мне привлекательным.
1) Хранить внутри каждого класса только те параметры, которые необходимы для построения. Остальные передаются из структуры, содержащей файл конфигурации, в функции-члены по мере необходимости.
class A {
int x_, y_;
public:
A(int x, int y, int Opt3) : ... {}
void Method1(int Opt1, int Opt2);
void Method2(int Opt1, int Opt4);
...
}
Плюсы: зависимость класса и его метода от параметров становится очевидной. Минусы: это также может привести к вызовам функций со многими параметрами. Это также не идеально, так как я должен явно указывать все параметры для каждого вызова этой функции, хотя параметры не меняются.
2) Передайте все параметры классу при построении и сделайте их закрытыми переменными-членами. Это приводит к конструкторам типа
class A {
int x_, y_, Opt1, Opt2, ...
public:
A(int x, int y, Opt1, Opt2, ...) : ... {}
//some methods
.
.
.
}
что раздражает, если нужно всегда явно указывать все параметры при создании нескольких объектов этого класса.
3) Сохраните все параметры в одной большой структуре. Сделайте общий указатель на эту структуру частной переменной-членом каждого класса. Плюсы: Конструктор принимает только один указатель. Минусы: Из интерфейса класса становится непонятно, какие параметры из конфигурации используются этим классом. Это может быть разъяснено комментариями.
4) Вдохновленный ответами в
Элегантный способ передачи нескольких аргументов в функцию
Определите вложенную структуру параметров в каждом классе, которая содержит необходимые параметры, например.
class A {
int x_, y_;
public:
A(int x, int y, Options& Opt) : ... {}
struct Options {
int Opt1 = default_value;
int Opt2 = default_value;
.
.
.
} Opt;
}
Плюсы: Из интерфейса становится понятно, какие опции использует этот класс. Эти параметры можно прочитать непосредственно из файла конфигурации, добавив функцию-член в класс параметров. Экземпляр такого конкретного набора параметров может быть создан пользователем без файла конфигурации, а значения по умолчанию могут быть изменены в зависимости от потребностей. Помимо общих параметров для создания класса, конструктору должен быть предоставлен только такой набор параметров. На самом деле это мой любимый подход.
Минусы: мне трудно различить, какие из параметров должны быть закрытыми переменными-членами класса или должны принадлежать набору параметров. Это приводит к вопросу о том, какими должны быть переменные-члены и какие есть опции для функций класса/члена. Есть ли у вас какие-либо советы?
Можете ли вы прокомментировать мои мысли и дать несколько советов?
Благодарю вас !