The question about Serialize class and CRuntimeClass

本文介绍MFC框架下如何实现对象的序列化,并通过一个具体示例详细讲解了使用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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值