2012-09-27 86 views
0

我必須序列化基類和派生類的CList。我怎樣才能做到這一點。MFC序列化

typedef CList<Student*, Student*> StVec; 

class Student : public CObject 
{ 
public: 
    DECLARE_SERIAL(Student); 

    Student(); 
    Student(Student& s); 
    Student(CString _name, CString _last, int _age); 
    virtual ~Student(void); 

    virtual void cin(); 
    virtual void cout(); 

    virtual void Serialize(CArchive& ar); 

    static Student* FromInput(); 

    inline const CString GetName(){return name;} 
    inline const CString GetLastName(){return last_name;} 
    inline const int GetAge(){return age;} 

    virtual inline Student& operator=(const Student &s) 
    { 
     name = s.name; 
     last_name = s.last_name; 
     age = s.age; 
     return *this; 
    } 

protected: 
    CString name; 
    CString last_name; 
    int age; 
}; 

class Warden : public Student 
{ 
protected: 
    virtual void Serialize(CArchive& ar); 
    UINT salary; 
}; 

class Group : public CObject 
{ 
public: 
    DECLARE_SERIAL(Group); 

    enum FindType { First = 0, Last, All}; 
    typedef bool (*StudentsFindCallback) (Student* student, void* condition); 

    Group(){ name = _T("Default Group"); } 
    Group(CString _name); 
    Group(Group& s); 

    ~Group(); 

    void CreateUser(); 
    void ShowUsers(); 
    //StVecOfIt FindUser(StudentsFindCallback f, void* condition, FindType ft); 
    inline Student* getStudent(POSITION pos) {return students->GetNext(pos); } 
    inline void DeleteUser(POSITION it){ students->RemoveAt(it); } 
    virtual void Serialize(CArchive& ar); 
    void Clean(); 

    /*static bool FindbyName(Student* student, void* condition); 
    static bool FindbyLastName(Student* student, void* condition); 
    static bool FindbyAge(Student* student, void* condition);*/ 

    virtual inline Group& operator=(const Group &s) 
    { 
     name = s.name; 
     students = s.students; 
     return *this; 
    } 

protected: 
    CString name; 
    StVec* students; 
}; 

void Student::Serialize(CArchive& ar) 
{ 
    CObject::Serialize(ar); 

    if (ar.IsStoring()) 
    { 
     ar.SerializeClass(Student::GetRuntimeClass());  
     ar << name << last_name << age; 
    } 
    else 
    { 
     ar.SerializeClass(Student::GetRuntimeClass()); 
     ar >> name >> last_name >> age; 
    } 
} 
void Group::Serialize(CArchive& ar) 
{ 
    ar.SerializeClass(RUNTIME_CLASS(Group)); 

    if (ar.IsStoring()) 
    { 
     ar << (int)students->GetCount(); 

     POSITION pos = students->GetHeadPosition(); 
     while(pos != NULL) 
     { 
      Student* student = students->GetNext(pos); 

      student->Serialize(ar); 
     } 
    } 
    else 
    {  
     Clean(); 
     int count = 0; 
     ar >> count; 

     for(INT_PTR i = 0; i < count; ++i) 
     { 
      Student* st = new Student(); 
      st->Serialize(ar); 
      students->AddTail(st); 
     } 
    } 
} 

我發現了一篇文章在codeproject但i'cant understend它。

Ofcourse我可以添加一個標誌,指示類的類型。此外,我可以序列化派生類,如果派生屬性爲空使用static_cast派生它的基類。或者我想用CArchive::ReadObjectCArchive::ReadClass來加載類,但是還有其他的方法嗎?

+0

你能提供一個示例代碼嗎? – zar

回答

0

我的MFC是生鏽的,但我相信這應該工作(未測試!)。

此外,您的Serialize()方法不應該爲其自己的類調用SerializeClass。主叫方決定給它打電話。例如,< <和>>操作符可以確定存檔中接下來的對象的類別。

void Student::Serialize(CArchive& ar) 
{ 
    CObject::Serialize(ar); 

    if (ar.IsStoring()) 
    { // No need for SerializeClass here. 
     ar << name << last_name << age; 
    } 
    else 
    { // No need for SerializeClass here. 
     ar >> name >> last_name >> age; 
    }  
} 
void Group::Serialize(CArchive& ar) 
{ 
    if (ar.IsStoring()) 
    { 
     ar << (int)students->GetCount(); 

     POSITION pos = students->GetHeadPosition(); 
     while(pos != NULL) 
     { 
      Student* student = students->GetNext(pos); 
      ar << student; // << includes class info about the serialized object 
     } 
    } 
    else 
    {   
     Clean(); 
     int count = 0; 
     ar >> count; 

     for(INT_PTR i = 0; i < count; ++i) 
     { 
      CObject *p; 
      ar >> p; // Deserialize whatever kind of object comes next 
      students->AddTail(p); 
     } 
    } 
}