У меня есть класс со многими переменными экземпляра:
class Data {
public:
const double a, b, c, d;
const size_t e, f, g, h, i, j;
const std::string s;
// and so on
double Q, Z;
Data(const double a, const double b, ...);
};
и некоторая довольно сложная логика в другом месте кода, которая вычисляет значения, которые должны иметь все эти поля, а затем создает Data
объект.
double a = ...;
double b = ...;
// and so on, but not for Q and Z
Data data_instance(a, b, c, d, e, f, g, h, i, j, s, ...);
Значения Q
а также Z
вычисляются в конструкторе, как функции других значений. Я делаю это так, потому что случаи Data
предназначены для того, чтобы быть неизменным, и я хотел бы, чтобы поля были const
чтобы помочь компилятору обеспечить это.
Насколько я знаю, это требует от меня определения конструктора
Data::Data(const double a, const double b, ...) : a(a), b(b), ... {}
который не действительно проблема, но с ~ 35 полями, это много кода, который очень формален и может в принципе генерироваться автоматически. Есть ли способ, которым я мог бы использовать хитрость синтаксиса C ++ или препроцессор для этого? В частности, я хотел бы дать список полей один раз, в некоторой форме и имеют объявления, параметры в конструкторе и инициализаторы в конструкторе — все они генерируются автоматически. Таким образом, когда мне нужно добавить новое поле в класс (что я должен делать время от времени, так как я добавляю новые функции), мне нужно только не забыть добавить это новое поле в одном месте.
Или было бы лучше просто отказаться от идеи const
-верность полностью? Если бы я сделал это, я мог бы создать Data data_instance()
используя конструктор по умолчанию и затем вычислить значения и присвоить их непосредственно его полям. Таким образом, мне нужно только объявить переменные, а не инициализировать их в конструкторе. (Если бы я мог, скажем, иметь поля, помеченные как const
но каким-то образом сделать так, чтобы они все еще могли быть изменены в теле конструктора, что сработало бы для меня.)
Если это действительно просто тривиальный «держатель» данных, рассмотрите возможность сделать его совокупным.
struct Data { // class works equally well...
double a, b, c, d;
size_t e, f, g, h, i, j;
std::string s;
};
Теперь вы используете это:
Data const d { 0,1,2,3, 111,222,333,444,555,666, "hello world" };
Обратите внимание, как d.s
это std::string const&
, поскольку const
распределяет между членами экземпляра.