Поля const в C ++ должны быть инициализированы в списке инициализации, что делает нетривиальным вычисление взаимозависимых значений из параметров конструктора.
Как лучше всего перевести, например, этот фрагмент кода Java на c ++?
public class SomeObject {
private final String some_string;
private final int some_int;
public SomeObject(final String input_filename){
SomeReader reader = new SomeReader(input_filename);
some_string = reader.getString();
some_int = reader.getInt();
reader.close();
}
}
Я думал об инкапсуляции подобъекта в SomeObject, но это только перекладывает проблему; или построение объекта с использованием статического метода:
class SomeObject {
private:
const std::string some_string;
const int some_int;
public:
static SomeObject unserialize(const char * input_filename){
SomeReader reader = new SomeReader(input_filename);
string str = reader.get_string();
int i = reader.get_int();
reader.close();
SomeObject obj(str, i);
return obj;
};
SomeObject(const std::string str, const int i) :
some_string(str),
some_int(i)
{};
}
Есть ли лучшее решение ?
Спасибо.
Это отличное приложение для делегирования конструктора C ++ 11:
class SomeObject {
private:
const std::string some_string;
const int some_int;
public:
// The "real" constructor for SomeObject
SomeObject(std::string str, const int i) :
some_string{std::move(str)},
some_int{i}
{}
// Deserialize from SomeReader (delegates to the primary constructor)
SomeObject(SomeReader& reader) :
SomeObject{reader.get_string(), reader.get_int()} {}
// Deserialize from SomeReader (accepts rvalues,
// delegates to the lvalue constructor)
SomeObject(SomeReader&& reader) :
SomeObject{reader} {}
// Deserialize from named file (delegates to the SomeReader&& constructor)
SomeObject(const char* input_filename) :
SomeObject{SomeReader{input_filename}} {}
};
Я думаю, что у вас правильный подход.
Я бы порекомендовал пару небольших изменений.
Это не правильно C ++.
SomeReader reader = new SomeReader(input_filename);
Возможно, вы имели в виду:
SomeReader reader(input_filename);
Вы можете изменить строки:
SomeObject obj(str, i);
return obj;
в
return SomeObject(str, i);
Вы можете использовать делегирование ctor и лямбда-функции, как это:
SomeObject(const char* filename) : SomeObject([&]{
/* Do calculations here */
return std::make_tuple(...);
}()) {}
SomeObject(std::tuple<...>&& x) : /* ... */ {}
Тем не менее, гораздо лучшая идея, вероятно, заключается в редизайне, чтобы использовать все то, что вы можете делать в C ++, а что нет в Java.