解析するには、https://github.com/nlohmann/jsonで、
std::vector<std::shared_ptr<VPN>>
ここで、VPN はサブタイプおよび 、 などのOpenVPN他のタイプにすることができます。次のことを行う必要がありました。MicrosoftVPNCiscoVPN
void to_json(json &j, const std::shared_ptr<VPN> &p)
{
//Dont forget to set type on each subtype!!!
if (auto pp = std::dynamic_pointer_cast<OpenVPN>(p))
{
to_json(j, pp);
}
else
{
//try other subtypes then throw if none
}
}
void from_json(const json &j, std::shared_ptr<VPN> &p)
{
if (j.at("type") == "OPENVPN")
{
p = std::make_shared<OpenVPN>();
//Important: re-set the type since we recreated the instance
p->type = VPN::Type::OPENVPN;
auto pp = std::dynamic_pointer_cast<OpenVPN>(p);
from_json(j, pp);
}
else
{
//throw
}
}
次に、サブタイプごとに and を実装しto_jsonますfrom_json。
void to_json(json &j, const std::shared_ptr<OpenVPN> &p)
{
//Important: always set type
j = json{
{"type", p->type},
{"openvpnVersion", p->openvpnVersion},
{"profile", p->profile}};
//...
}
void from_json(const json &j, std::shared_ptr<OpenVPN> &p)
{
j.at("openvpnVersion").get_to(p->openvpnVersion);
j.at("profile").get_to(p->profile);
//...
}
ご覧のとおり、 のような多くの問題が発生しif (j.at("type") == "OPENVPN")ました。VPNたとえば、サブタイプを使用してインスタンスを作成する前に、列挙型ではなく文字列リテラルと比較する必要がありますOpenVPN。自分が何をしているのかを理解するために、多くのセグメンテーション違反の後、何度も試行しました。また、ポインターを自分でインスタンス化する必要がありますが、これは非常に忘れやすく、segfault を引き起こします。
とforstd::vector<CustomObject>を実装する以外に何もしなくても動作するようです。しかし、その場合はand forを実装する必要があります。from_jsonto_jsonCustomObjectCustomObject = std::shared_ptr<OtherCustomObject>from_jsonto_jsonstd::shared_ptr<OtherCustomObject>
ライブラリがstd::vector<std::shared_ptr<CustomObject>>独自に処理するべきではないか、または処理できませんか? 誰かがより良い解決策を持っていますか?