Как отделить клиентский класс от шаблонного класса?

0

Предположим, у меня есть шаблонный класс:

template<typename T>
struct Node
{
    T val;
    Node *next;
};

template<typename T>
class MyClass
{
     T data1_;
     T data2_;
     vector<Node<T> >  vi_;
};

Теперь я хочу сериализовать MyClass на диск, используя другой метод. Например, при использовании сырья C Система вызова записи/чтения или 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);}
     ...
}

Он может работать. Но это кажется не изящным.

Стратегия - хорошее решение, но функция шаблона не может быть виртуальной.

Есть ли лучший способ сделать это?

  • 1
    Сплит сериализация / десериализация из вашей модели. Обычно их не рекомендуется смешивать. Я бы предложил написать шаблонный шаблон класса template<typename T> Serializer со статическим методом с именем save (аналогично вашим RawC и StreamCPP ), а затем использовать специализацию шаблона для его реализации для каждого класса, который необходимо сериализовать. Другим подходом могут быть общие классы / интерфейсы DAO в сочетании с DAOManager обеспечивающим доступ (это был бы подход, более похожий на OO / java).
  • 0
    Посмотрите, как работают черты итераторов, черта - это отдельная структура, которую вы специализируете для своих собственных итераторов. Ваш "MyClass" будет просто обращаться к этой структуре, когда ему нужно будет что-то делать. Вместо того, чтобы передавать в обработчик.
Теги:
templates

1 ответ

1
Лучший ответ

Вы можете сделать что-то вроде этого:

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

    }
};

Ещё вопросы

Сообщество Overcoder
Наверх
Меню