如何将客户端类与模板类解耦

How to decouple client class with a template class?

本文关键字:解耦 客户端      更新时间:2023-10-16

假设我有一个模板类:

template<typename T>
struct Node
{
    T val;
    Node *next;
};
template<typename T>
class MyClass
{
     T data1_;
     T data2_;
     vector<Node<T> >  vi_;
};

现在我想使用不同的方法将MyClass串行化到磁盘。例如,使用原始c系统调用write/read或c++fstream,或其他方法。

我介绍了另一个模板参数:

template<typename T,typename SerializerTrait>
class MyClass
{
     T data1_;
     T data2_;
     vector<Node<T> >  vi_;
     void save()
     {
           SerializerTrait::save(data1_);
           SerializerTrait::save(data2_);
           SerializerTrait::save(vi_);
     }
};

//serializer
template <typename>
class RawC 
{
     static FILE *f;
     static void save(T t){fwrite(&t,sizeof(t),1,f);}
     ...
}
template <typename>
class StreamCPP
{
     static fstream *f;
     static void save(T t){*f<<t);}
     ...
}

它可以工作。但它似乎并不优雅。

策略模式是一个很好的解决方案,但模板功能不能是虚拟的。

有更好的方法吗?

您可以这样做:

template<typename T>
class MyClass
{
    template <class SERIALIZER>
    void save()
    {
        SERIALIZER::save(data1_);
        SERIALIZER::save(data2_);
        SERIALIZER::save(vi_);
    }
    //or with serializer instance
    template <class SERIALIZER>
    void save(SERIALIZER & s)
    {
        s.save(data1_);
        s.save(data2_);
        s.save(vi_);
    }
    virtual void save(SerializerDetail * s)
    {
        s->save(this);
    }
};
class SerializerDetail
{
public:
    template <class T>
    void save(T * p)
    {
        p->save<SomeSerializer>();//use the first two save functions
        //or
        p->save(SerializerInstance);//or this of you want it
    }
};