本文介绍了与序列多态类型常见的混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我见过很多问题,教程和文档涉及序列化派生类的,我一直没能达到的几个问题,包括达成共识(并在以下code所示):
-
的boost ::系列化:: base_object
VSBOOST_SERIALIZATION_BASE_OBJECT_NVP
-
归档和放大器; MDATA;
VS归档和放大器; BOOST_SERIALIZATION_NVP(MDATA);
-
BOOST_SERIALIZATION_ASSUME_ABSTRACT的用处(AbstractPoint);
- 要求
连载()
在分级中的类,这并不需要序列化任何东西。
code:
的#include<升压/存档/ text_oarchive.hpp>
#包括LT&;升压/存档/ text_iarchive.hpp>
#包括LT&;升压/系列化/ shared_ptr.hpp>
#包括LT&;升压/系列化/ base_object.hpp>#包括LT&;&的fstream GT;类AbstractPoint
{
上市:
虚拟〜AbstractPoint(){}
虚拟无效的doSomething()= 0; //即使是一个抽象类,我们仍然需要这种
模板<类TArchive>
无效连载(TArchive&安培;归档,const的无符号整型版)
{
// 没做什么
}
};//这似乎并不做任何事情
// BOOST_SERIALIZATION_ASSUME_ABSTRACT(AbstractPoint);Point类:公共AbstractPoint
{
上市:
点()=默认值;
点(const的双倍数据):MDATA(数据){} 无效DoSomething的(){} 模板<类TArchive>
无效连载(TArchive&安培;归档,const的无符号整型版)
{
//这两个看似相同的。如果没有他们中的一个,未注册的投无效
归档和放大器;提高::系列化:: base_object< AbstractPoint>(*此);
//归档和放大器; BOOST_SERIALIZATION_BASE_OBJECT_NVP(AbstractPoint); //这两个看似等价
归档和放大器; MDATA;
//归档和放大器; BOOST_SERIALIZATION_NVP(MDATA);
} 双MDATA;
};诠释的main()
{
的std :: shared_ptr的< AbstractPoint>点(新点(7.4)); 的std ::的ofstream的OutputStream(的test.txt);
提高::档案:: text_oarchive的outputArchive(OutputStream中);
outputArchive.register_type<点和GT;();
outputArchive<<点;
outputStream.close(); 的std :: shared_ptr的< AbstractPoint> pointRead;
性病:: ifstream的InputStream的(的test.txt);
提高::档案:: text_iarchive inputArchive(InputStream的);
inputArchive.register_type<点和GT;();
inputArchive>> pointRead; 的std :: shared_ptr的<点和GT; castedPoint =的std :: dynamic_pointer_cast<点和GT;(pointRead);
性病::法院LT&;< castedPoint->&MDATA LT;<的std :: ENDL;
返回0;
}
另一个主要问题就是在一个真实的环境中注册类(当有链接等),但似乎值得一个单独的问题。
这将是巨大的,有这样的东西在文档中的金标准的例子,但在至少在计算器上:)
解决方案
-
的boost ::系列化:: base_object
VSBOOST_SERIALIZATION_BASE_OBJECT_NVP
该NVP包装只会被要求有元素命名,如XML存档。
除非你使用它, base_object<方式>
是更清洁和更简单
-
归档和放大器; MDATA;
VS归档和放大器; BOOST_SERIALIZATION_NVP(MDATA);
同上
-
BOOST_SERIALIZATION_ASSUME_ABSTRACT的用处(AbstractPoint);
我以为这只会是一个最优化 - SUP pressing注册类型与每个存档类型的信息,因为你告诉框架它永远不会被反序列化该类型的实例
- 要求
连载()
在分级中的类,这并不需要序列化任何东西。
您不需要它,除非你需要大约多态基有类型的信息。当你需要的?当你需要为基本类型的反序列化的指针。
因此,如果你有
结构A {虚拟〜A(); };
结构A:A {};结构C:B {};
结构D:B {};`
在将的需要 A
序列化(但不是 B
)如果你( DE)连载 A *
。您需要序列化 B
如果你(反)序列化 B *
。
同样,如果你的类型是不是多态(虚拟),或者你不使用它是这样,你不需要任何基础的序列化(例如,如果你(反)序列化 C
或 D
直接)。
最后,如果你有结构A {};结构A:A {};
没有必要向大家介绍的基本类型升压序列化可言,(你可能只是做系列化从 B在
)。
更新响应您的样品:
- 看起来不错
-
需要即可调用基序列当然;不一定使用base_object因为你需要多态序列化:
模板<类TArchive>无效连载(TArchive&安培;存档,无符号){
归档和放大器;提高::系列化:: base_object< AbstractPoint>(*此)
&安培; MDATA;
// 要么:
归档和放大器;的static_cast< AbstractPoint&安培;>(*此)
&安培; MDATA;
//甚至只是:
归档和放大器; mParentData
&安培; MDATA;
} -
:的确,它酷似情形1,但与动态分配和目标跟踪
-
:酷似情形1,但与动态分配和对象跟踪; NB!它需要为基本明确序列化!
模板<类TArchive>无效连载(TArchive&安培;存档,无符号){
归档和放大器;提高::系列化:: base_object< AbstractPoint>(*此)
&安培; MDATA;
} -
:是的,但它是更典型的使用
CLASS_EXPORT *
从升压/系列化/ export.hpp
宏
这篇关于与序列多态类型常见的混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!