The question about Serialize class and CRuntimeClass

    We all know class can't store in memory directly.But also we have our own method to load it into memory.MFC CObject give a
override fuction Serialize can satisfy our need.Here,I give you a example for serialize!
   first of all,I should create a Person class as a object example,which must inherit from MFC CObject otherwise you can't
get a serial class.we must talk about CRuntimeClass, which you must master it how to create a objct class and make use of it
fluently if you wanna get a serial class from a file or something else. so what is it? maybe you never use it and you just only see from here,but it's OK,I will tell you about CRuntimeClass Details.Let me see the MFC give it definition.
  Its structure like this:
struct CRuntimeClass
{
// Attributes
 LPCSTR m_lpszClassName;
 int m_nObjectSize;
 UINT m_wSchema;                                     // schema number of the loaded class
 CObject* (PASCAL* m_pfnCreateObject)();             // NULL => abstract class
 CRuntimeClass* (PASCAL* m_pfnGetBaseClass)();
                .
                .
                .
 CRuntimeClass* m_pBaseClass;

// Operations
 CObject* CreateObject();
 BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const;

// Implementation
 void Store(CArchive& ar) const;
 static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum);

                                       // CRuntimeClass objects linked together in simple list
 CRuntimeClass* m_pNextClass;          // linked list of registered classes
};
I write an application of Win32 Console precdure as a CRutimeClass example.

#include<iostream>
#include<CString>
using namespace std;
class CObject;
struct CRuntimeClass
{
char *m_lpszClassName;                        //name class
CObject *(__stdcall* m_pfnCreateObject)();    //function pointer of object constructor
CObject *_stdcall CreateObject();             //definition
};

class CObject
{
 public:
     virtual void show()
                     {cout << "hi---> CObject!" << endl; }
};
class myClass :public CObject
{
 public:
       virtual void show()
                  { cout << "hi---->myClass!" << endl;}
public:
  static CRuntimeClass classMyclass;          //define CRuntimeClass variable as information table
  static CRuntimeClass *GetRunTimeClass();    //Get function of pointer from informatin table
};
CObject *__stdcall CeateObject()
{
   return new myClass;
}
CRuntimeClass myClass::classMyclass = {"myClass",CreateObject};
CRuntimeClass *myClass:GetRuntimeClass()
{
  return &myClass::classMyClass;
}

// main function
void main(void)
{
char _lpszCLS[10];
cout << "please input class name:" ;
cin >> _lpszCLS;
CRuntimeClass *p = myClass::GetRuntimeClass();
if (!strcmp(p->m_lpszClassName,_lpszCLS))
{
   CObject *_stdcall pp = p->m_pfnCreateObject();
   pp->show();
}
else
{
   cout << "can't find class name!" << endl;
}
}
  If you create a class like this form :
 class myClass:public CObject
{
    private:
         int m_X;
public:
     myClass(int x):m_X(x){}                         //here,you should notice it???
   virtual void show() {cout << "sth...." << endl;}
   public:
      static CRuntimeClass classMyclass;
      static CRuntimeClass *GetRuntimeClass();
};

  you will see  "error......"  why? do you know why? because constructor can't have parameter if you wanna create a class
dynamicly. you must define a constructor that not have parameter.I give you a simple application using serial and CRuntimeClass. here,you must inpocorate the IMPLEMENT_SERIAL macro and declare DECLARE_SERIAL .
  class Person:public CObject
   {
     public:
        Person();
 virtual ~Person();
        void show();
     public:
        CString m_Name;
 int m_Age;
 CString m_Gender;
     public:
        virtual void Serialize(CArchive &ar);
     DECLARE_SERIAL(Person)
   };
//..........cpp
  IMPLEMNET_SERIAL(Person,CObject,1)
   void Person::show()
   {
     CString strTemp;
     strTemp.Format(_T(%s:%d:%s),this->m_Name,this->m_Age,this->m_Gender);
   }
   
 void Person::Serialize(CArchive &ar)
 {
      if (ar.IsStoring())
        {
           ar << m_Name << m_Age << m_Gender;
        }
        else
        {
          ar >> m_Name >> m_Age >> m_Gender;
        }
 }
 I create a Dialog for display Person object like this:
   void CSerialDlg::OnShow()
{
 // TODO: Add your control notification handler code here
 pPerson = new Person();
 this->pPerson->m_name = _T("xiaohe");
 this->pPerson->m_age = 23;
 this->pPerson->m_sex = _T("male");
 this->pPerson->show(); //
 delete pPerson;
}

void CSerialDlg::OnShowFile()
{
 // TODO: Add your control notification handler code here
 pObj = new Person();
 this->pObj->m_name = _T("xiaohe");
 this->pObj->m_age = 23;
 this->pObj->m_sex = _T("male");

 //將對象person序列化到文件中
 CFile myFile;
 myFile.Open("d://mydata.txt",CFile::modeCreate|CFile::modeWrite);
 CArchive ar(&myFile,CArchive::store);
 ar << pObj;
 ar.Close();
 myFile.Close();
 delete pObj;
 
}
void CSerialDlg::OnReadShow()
{
 // TODO: Add your control notification handler code here
 CObject *pObj = NULL;
 CFile myFile;
 myFile.Open("d://mydata.txt",CFile::modeRead);
 CArchive ar(&myFile,CArchive::load);
 ar >> pObj;
                                                    //判斷對象的數據了類型;
 CRuntimeClass *pClassObj = pObj->GetRuntimeClass();//運行時的類
 CString strTemp(pClassObj->m_lpszClassName);
 if (strTemp == "Person")                           //判斷是不是Person類
 {
     Person *pPerson = (Person*)pObj;
     pPerson->show();
 }
 else
 {
  AfxMessageBox(_T("It's not what you wanna get Object"));
 }
 ar.Close();
 myFile.Close();
}
Pay attention to the last function,it create a class dynamicly and get the object that whether what you need or not.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章