2010-11-21 14 views
2

olmadan bir sınıf hiyerarşisi serisini nasılBir sınıf hiyerarşisi serialize ve serisini bu yaklaşımı kullanıyorum bir sınıf numaralayıcısı

// Enumeration of classes. 
struct Type { 
    enum TypeEnum { A, B } 
    TypeEnum t; 
    Type(TypeEnum te) : t(te) { } 
    bool operator == (TypeEnum te); 
    void saveToStream(Stream& stream); 
    void loadFromStream(Stream& stream); 
}; 

// Serializable base class. 
struct A { 
    Type type; 
    A() { type = Type::A; } 
    // ... members 
    virtual void loadFromStream(Stream& stream); 
    virtual void saveToStream(Stream& stream) const; 
}; 

// Serializable child class. 
struct B : public A { 
    B() : A() { type = Type::B; } 
    virtual void loadFromStream(Stream& stream); 
    virtual void saveToStream(Stream& stream); 
}; 

// Helper class. 
struct Serializer { 
    static A* loadFromStream(Stream& stream) 
    { 
     Type t; 
     t.loadFromStream(stream); 
     if (t == Type::A) { 
      A* a = new A; 
      a->loadFromStream(stream); 
      return a; 
     } else if (t == Type::B) { 
      A* b = new B; 
      b->loadFromStream(stream); 
      return b; 
     } 
     throw "Unknown type"; 
     return 0; // surpress warning 
    } 
    static void saveToStream(Stream& stream, const A& a) 
    { 
     a.type.saveToStream(stream); 
     a.saveToStream(stream); 
    } 
}; 

// Usage 
B b; 
Serializer::saveToStream(stream, b); 
B* b2 = static_cast<B*>(Serializer::loadFromStream(stream)); 

Bu yaklaşım oldukça basit ve anlaşılması kolaydır. Ama sınıf hiyerarşisini her genişlediğimde, Type sınıfını güncellemeye gerek kalmadan daha zarif bir çözüm var mı diye düşünüyordum.

Type numaralandırma sınıfı olmadan ve belki de Serializer sınıfı olmadan nasıl yapılacağına dair herhangi bir ipucunuz var mı?

+0

Eh, evet, olasılıklar var. Hem statik hem de dinamik kayıt yapabilirsiniz, ancak uygulama gerçekten koymak istediğiniz yere bağlıdır. Yapı sisteminde bulunabilir, makro/şablon meta programı kullanılarak oluşturulabilir veya dinamik bile olabilir. –

+0

http://stackoverflow.com/questions/4229748/pattern-for-delegation-to-sub-component/ çoğaltması? –

cevap

2

Bu, Factory Pattern için iyi bir aday gibi görünüyor. Temel olarak, belirli bir tanımlayıcıya dayalı olarak doğru tür başlatmanın sorumluluğunu verme görevinden oluşur. Yığın Taşması üzerinde yapılan bir arama, C++ uygulamasına güzel bir örnek sağlayan this answer'u getirdi. Fabrika tarafından oluşturulabilecek tüm nesnelerin ortak bir arabirim (bu sizin durumunuz gibi görünüyor) uygulaması gerektiğini unutmayın. Eğer desen bu tür uygulamak kez

, sen Serializer::loadFromStream içinde if/else if kaskad çıkarıp sadece fabrika örneği nesne üzerinde loadFromStream aramak mümkün olacak.

+0

Bu, bu arada, [QUiLoader] (http://doc.qt.nokia.com/latest/quiloader.html) tarafından kullanılan bir yaklaşımdır (tabii ki XML'e serileştirilmiş olsa da). – andref

+0

Sağlanan örneğe baktığımda, eğer 'if/else' ifadesinin daha basit bir yaklaşım ve anlaşılması daha kolay bir yol olduğuna inanıyorum. – WolfgangA