C++中,不同类的实例的序列化问题

        假设编写一个图形编程程序,所有的图形类都有共同的父类Graphics。Graphics类中提供了进行序列化的接口Serialize()。
        现在当用户使用该图形编辑器创建了多个图形对象(即创建了多个Graphics的子类的实例,这些实例可以通过一个chain of responsibility连接起来),并希望将该图形保存到一个文件里面。我们需要遍历该职责链,依次调用每个实例的Serialize方法。
        问题随之产生:我们如何读取这些记录呢?我们怎么知道当前的读取的数据是哪个子类的实例的数据呢?产生这个问题的根本在于我们无法将类的类型信息保存到文件中

         一个解决办法是:在存入文件的时侯,每个类都写入一个唯一的ID信息;那么在读入的时侯,我们可以通过该ID信息知道这是哪个类的实例的数据。大概的代码可能是这样的:
void Serialize(CArchive & ar){
    if(ar.IsLoading){
        ar>>id;
        switch(id){
        case SUB_CLASS1:
            newInstance=new SubClass1;
            break;
        case SUB_CLASS2:
            newInstance=new SubClass2;
            break;
        // ...
        }
        newInstance.Serialize(ar);
    }
}

但是这似乎并不是一个好方法,因为每次当我们新增加一个子类的时侯,都需要为其手工增加一个id,而且需要在上面代码中的switch...case结构中增加一个相应的入口。当子类的数目众多,或者子类的种类在不断变化的时候,这样做就非常不可靠了。
        其实可以通过类型注册来解决这个问题。
        首先解决ID的问题,这个可以借助Loki库的Typelist(参见我的另外一篇文章)。
        我们可以使用一个数据结构来保存所有的子类的信息(通过保存一个该类的实例的方式来保存该类的信息)
class AbstractBuilder{};
template <class T> class Builder:public AbstractBuilder
{
public:
    T* clone(){ return new T;}
};
//...
void RegsiterClassInfo()
{
    classInfoList.push_back(Builder<SubClass1> tmp1);
    classInfoList.push_back(Builder<SubClass2> tmp2);
    // ...
}
void Serialize(CArchive& ar)
{
    ar>>id;
    for(iter=classInfoList.begin();iter!=classInfoList.end();++iter){
        if(id == iter->id){
            newInstance= iter->Clone();
            break;
        }
    }
    newInstance->Serialize(ar);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值