MFC序列化 [英] MFC serialization

查看:90
本文介绍了MFC序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须序列化基类和派生类的CList.我怎样才能做到这一点.

i have to serialize a CList of base and derived classes. How can i do that.

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 found an article at the codeproject but i'cant understend it at all.

当然,我可以添加一个指示类类型的标志.我也可以序列化到派生类,如果派生属性为空,请使用static_cast派生到基类.或者我正在考虑使用CArchive::ReadObjectCArchive::ReadClass来加载类,但是还有另一种方法吗?

Ofcourse i can add a flag which indicate the type of class. Also i can serialize to derived class and if the derived properties are empty use static_cast to derive it to base class. Or i'am thinking of using CArchive::ReadObject or CArchive::ReadClass to load classes, but is there another way to do it?

推荐答案

我的MFC生锈了,但我认为这应该可以工作(未经测试!).

My MFC is rusty but I believe this should work (not tested!).

此外,您的Serialize()方法永远不要为自己的类调用SerializeClass.由调用者决定调用它.例如,<<和>>运算符可以识别归档文件中紧随其后的对象的类.

Also, your Serialize() method should never call SerializeClass for its own class. It's up to the caller to decide to call it. For instance, the << and >> operators do it to identify the class of the object that comes next in the archive.

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); 
        } 
    } 
} 

这篇关于MFC序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆