2

我正在寻找一种在 C++ 中序列化大型复杂对象的方法。我一直在考虑使用 boost 序列化 api,但我不确定是否可以序列化以这种方式实现的对象。

在我的程序中,我有以下对象:

typedef map<float, float> SignalData;
typedef pair<float,float> TimeValuePair;

class SignalDatabaseNG : public SignalDatabase
{
   (...)
   private:
      vector<SingleSignal *> all_signals;
   (...)
};

class SingleSignalAsStdMap: public SingleSignal{
   private:
       SignalData * signalData;
   (...)
};

class IntegrationComparator : public Comparator {
   private:
      map<SignalData *, float> * preComputedIntegrals;
   (...)

   public:
       IntegrationComparator();
       float compare(SignalData *a, SignalData *b);
       void preComputeIntegralsForAll(SignalDatabase * database);
   (...)
 };

SignalDatabase 是一个类,其最重要的作用是保存程序所需的所有数据。信号表示为两个浮点数(时间和值)的映射,所有信号都保存在此类映射的向量中。

它通过以下方式填充数据:

SignalDatabaseNG * signalDatabase = TestConfiguration::getSignalDatabase();
IntegrationComparator * integrationComparator = new IntegrationComparator();
integrationComparator->preComputeIntegralsForAll(signalDatabase);

TestConfiguration::getSignalDatabase()返回一个数据库对象,其中包含计算积分所需的数据(在程序运行开始时从文本文件中读取)。然后,integrationComparator对象被创建并被preComputeIntegralsForAll(SignalDatabase * db)调用,它执行计算。最后,map<SignalData *, float> * preComputedIntegrals里面integrationComparator充满了数据。

这种积分计算需要大量时间(10 个信号大约需要 60 秒,我需要为 ~220000 个信号计算它)。

我希望能够运行一次,然后对其进行序列化,然后在每个程序运行时重用它(数据不会经常更改,因此可以节省大量时间)。

问题是映射将指向信号对象的指针映射到整数值。但是,在下一次运行中,数据库将从头开始创建,并且指针内的所有地址都会更改。可以同时序列化信号数据库和预先计算的积分数据库,但是也不能保证反序列化后数据库中的信号会在内存中的相同位置,因此integralsComparator 中的指针也会完全错误。

有没有人知道如何进行这种序列化(最好不必重写类的整个结构)?

4

2 回答 2

3

boost 序列化可以处理指向对象的指针,即使它们是多态的。库将序列化指向的对象(并注册其类型),当从存档中读取时,将创建对象的新实例,反序列化并填充指针。

这个问题的答案详细说明了您需要做些什么来帮助库在反序列化时识别派生类。

这也适用于 shared_ptrs 和其他智能指针(提示、提示)。

此外,boost 序列化还可以为您跟踪您的对象,因此当两个指向同一对象的指针被序列化时,该对象仅被序列化一次。

您的设计中有趣的部分是您使用指针作为地图的键。这可能有效(在某些方面,地图只是对的容器),但我从未尝试过使用 boost 序列化。

于 2013-09-19T22:00:28.263 回答
2

可以使用 boost 序列化来序列化和反序列化由指针和指针集合持有的对象。请参阅教程/指针

于 2013-09-19T21:58:55.893 回答