无法将对象反序列化为其类,但只能作为其父类
Posted
技术标签:
【中文标题】无法将对象反序列化为其类,但只能作为其父类【英文标题】:Unable to deserialize object as its class, but only as its parent's 【发布时间】:2015-07-13 15:05:41 【问题描述】:我有一个服务器接收使用 boost 序列化 text_archive 序列化的数据。到达的数据可以是以下MB_BPRequest
或MB_BPResponse
之一,两者都扩展MB_BPMessage
。
所以我有这个代码:
request_callback(MB_BPRequest);
response_callback(MB_BPResponse);
try
MB_BPRequest req;
archive >> req;
request_callback_(req);
catch (std::exception& e)
MB_BPResponse resp;
archive >> resp;
response_callback_(resp);
奇怪的是,如果我使用基类,它只会反序列化存档:
MB_BPMessage req;
archive >> req;
request_callback_(/*cast somehow*/req);
否则会引发“输入流错误”。
问题在于我不能将MB_BPMessage
转换为MB_BPRequest
或MB_BPResponse
,因为编译器会抛出错误。
我有兴趣了解解决此问题的其他方法。
【问题讨论】:
【参考方案1】:您只能通过指针(反)序列化多态类型。见
文档http://www.boost.org/doc/libs/1_58_0/libs/serialization/doc/serialization.html#derivedpointers特别是如果你真的必须通过引用序列化这些,你将不得不手动处理所有权语义:
文档:http://www.boost.org/doc/libs/1_58_0/libs/serialization/doc/serialization.html#references我们通过序列化引用来解决这些问题,就好像它们是指针一样。
【讨论】:
问题在于MB_BPRequest
和MB_BPResponse
实际上并不是多态的——它们只是与它们的基类MB_BPMessage
共享一些功能,但没有虚拟方法。跨度>
@Mak 在这种情况下,您为什么期望能够提取与序列化不同的类型 (MB_BPMessage
)?那只是一个错误。您可能想改用boost::variant<MB_BPRequest, MB_BPResponse>
- 只要您序列化与反序列化相同的类型
对不起,如果我的问题不够清楚。当我序列化MB_BPRequest
时,我只能将其反序列化为MB_BPMessage
,否则我会遇到异常。我会看 int boost::variant。谢谢
我认为我的评论是正确的。你只是没有显示序列化代码,但我敢打赌它序列化了MB_BPMessage
...如果没有,请将相关代码添加到问题中(SSCCE)
下面是一个全面的示例,显示了可能出现的问题:Live On Coliru。还要注意不兼容的反序列化如何甚至不会引发错误(在这里它会默默地返回错误的结果)。 live-stream recording 仍然可用以上是关于无法将对象反序列化为其类,但只能作为其父类的主要内容,如果未能解决你的问题,请参考以下文章
使用 JsonConvert.DeserializeObject 或 JObject.Parse 将类反序列化为 c# 中的字典