Могу ли я иметь простой конструктор, сгенерированный только из объявлений?

У меня есть класс со многими переменными экземпляра:

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 но каким-то образом сделать так, чтобы они все еще могли быть изменены в теле конструктора, что сработало бы для меня.)

-1

Решение

Если это действительно просто тривиальный «держатель» данных, рассмотрите возможность сделать его совокупным.

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 распределяет между членами экземпляра.

5

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


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