gpt4 book ai didi

c++ - 使用 C++ 技术的代码更少

转载 作者:搜寻专家 更新时间:2023-10-31 02:13:27 25 4
gpt4 key购买 nike

我们有一个简单的 c++ 任务来解析来自 http 端点的大 json 文件,然后将值复制到自定义本地类实例。 (在下面的代码中,实例是 obj,带有 setter setField1setField2 等)

这段代码很“简单”,但是 json 响应很大,会产生一个非常大的 c++ 文件来做同样的事情。但是,有一些事情需要考虑,即不同的类型和 setter 方法名称。以下是 3 种情况(一个 int、一个 bool 和一个 double),但我的代码至少包含 50 种类型。我如何才能使代码现代化,使其不易出错并减少代码行数?

if ( item_[i].HasMember("field1") && item_[i]["field1"].IsDouble()) {

double v = item_[i]["field1"].GetDouble();
if ( v < 0 )
throw CustomException("field1 value invalid");

obj.setField1(v);

} else {
throw CustomException("field1 missing or wrong data type");
}

if ( item_[i].HasMember("field2") && item_[i]["field2"].IsBool()) {

bool v = item_[i]["field2"].GetBool();

obj.setField2(v);

} else {
throw CustomException("field2 missing or wrong data type");
}

if ( item_[i].HasMember("field3") && item_[i]["field3"].IsInt()) {

int v = item_[i]["field3"].GetInt();
if ( v < 0 )
throw CustomException("field3 value invalid");

obj.setField3(v);

} else {
throw CustomException("field3 missing or wrong data type");
}

最佳答案

这个序列化代码中最邪恶的是,恕我直言,重复和那些字符串标识符。在这里我将发布我的 C++ 伪代码两分钱(我不会使用 setter,但这个想法可以很容易地扩展到使用它们)。当然,此解决方案可能无法从一开始就适合您的代码,但这只是总体想法的概述。

首先,这里是一些可序列化对象的声明:

class TestObject : public JsonSerializable
{
public:

TestObject()
{
// String field names are localized in a single place
// Here we create some sort of mapping from JSON to
// actual data.
addField("bool", &m_bool);
addField("int", &m_int);
addField("string", &m_string);
}

private:

bool m_bool
int m_int;
std::string m_string;
};

现在让我们定义一个 JsonSerializable 类来处理从 JSON 文件加载对象:

class JsonSerializable
{
public:

// This method iterates all registered fields
// and tries to read them from a JSON
void load(const Json& json)
{
for (const auto& kv : m_fields)
{
kv.second->set(json[kv.first]);
}
}

protected:

// This method was used in a TestObject constructor
template<typename TValue>
void addField(const std::string& name, TValue* value)
{
m_fields[name] = new GenericField(value);
}

private:

// A map to store all fields to be loaded from JSON
// (can be a list, vector or any other favourite container)
std::map<std::string, GenericField*> m_fields;
};

最后但并非至少,一个字段解析器接口(interface):

// An interface that is exposed to JsonSerializable that hides
// a type-specific serialization process.
class Field
{
public:

// Contains just one method to set a field from a JSON value.
virtual void set(const JsonValue& value) = 0;
};

// Generic type-specific implementation
template<typename TValue>
class GenericField : public Field
{
public:

// Each field contains a pointer to a field, but here you can
// also use pointer to a method or std::function to add setters.
GenericField(TValue* value)
: m_value(value)
{

}

// And here is an actual serialization code, that extracts a
// value from a JSON and writes to a pointed chunk of memory.
virtual void set(const JsonValue& value)
{
*m_value = value.as<TValue>();
}

private:

TValue* m_value;
};

因此这里的基本思想是通过将实际的序列化代码隐藏在 Field 接口(interface)后面并在一个地方本地化字符串标识符来消除代码重复 - 在可序列化对象的构造函数中。

希望这对您有所帮助。

关于c++ - 使用 C++ 技术的代码更少,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41397680/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com