与序列多态类型常见的混乱

与序列多态类型常见的混乱

本文介绍了与序列多态类型常见的混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我见过很多问题,教程和文档涉及序列化派生类的,我一直没能达到的几个问题,包括达成共识(并在以下code所示):


  • 的boost ::系列化:: base_object VS BOOST_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 VS BOOST_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在)。

更新响应您的样品:


  1. 看起来不错

  2. 需要即可调用基序列当然;不一定使用base_object因为你需要多态序列化:

     模板<类TArchive>无效连载(TArchive&安培;存档,无符号){
        归档和放大器;提高::系列化:: base_object< AbstractPoint>(*此)
                &安培; MDATA;
        // 要么:
        归档和放大器;的static_cast< AbstractPoint&安培;>(*此)
                &安培; MDATA;
        //甚至只是:
        归档和放大器; mParentData
                &安培; MDATA;
    }


  3. :的确,它酷似情形1,但与动态分配和目标跟踪


  4. :酷似情形1,但与动态分配和对象跟踪; NB!它需要为基本明确序列化!

     模板<类TArchive>无效连载(TArchive&安培;存档,无符号){
        归档和放大器;提高::系列化:: base_object< AbstractPoint>(*此)
                &安培; MDATA;
    }


  5. :是的,但它是更典型的使用 CLASS_EXPORT * 升压/系列化/ export.hpp


这篇关于与序列多态类型常见的混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 09:48