程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 實現多種類型的序列化

實現多種類型的序列化

編輯:C++入門知識

還有的一點從文件---->內存--------->對象的恢復 沒有構造函數的調用 ,這一點很神奇 。。。
我們成功的恢復了2個對象但是卻沒有發生構造函數的調用...之所以我這種序列化方式能成功 ,肯定是在編譯器內部對於這種方式做了某種
支撐所以我說微軟MFC的序列化方式可能是這種方式。。。
 

 

\

#include <iostream>
#include <fstream>
#include <string>
using  namespace std ;
class Base

public:
   /*  Base類型提供了統一的實現 ,所有需要序列化的類必須繼承自Base類 包括成員對象
   *   LoadObject  LoadObject 在這裡不需要多態機制 單獨作為功能的實現
   *   length 為對象的實際長度 為了避免在內存重分配過多的內存浪費空間
   *   long length=sizeof(*obj) ;  //不可以這樣做因為 我們發現實際上sizeof這個運算符
   *    在操作的時候獲取的是當前運行時類型所指對象的大小 如果向上轉型那麼會進行窄化處理 獲得的大小是1 所以這裡要傳遞實際大小www.2cto.com
   *   LoadObject  LoadObject作為Base的靜態方法分別提供序列化和反序列化的功能
   */
    static void StoreObject(Base *obj,string file,int length)  
    {  
       cout<<"對象寫入到文件..."<<endl ;
        ofstream *o=new ofstream(file.c_str()) ;
     o->write((char*)obj,length) ;
  o->close() ;
  delete o ;
    }
    static Base* LoadObject(string file,int length) 
  {
   cout<<"從文件恢復對象..."<<endl ;
   if(Base::tem_object!=NULL)
      return Base::tem_object ;
         char *buf=new char[length] ;
      ifstream i(file.c_str()) ;
      i>>buf ;
      Base *p=(Base*)buf ;
   Base::tem_object=p ;
   i.close() ;
   return (p);
  }
 /*
 * 構造器用做一些初始化操作
 */
 Base()
 {
    
 cout<<"基類構造中..."<<endl; }
 /*
 *  釋放反序列化時候分配的空間
 */
 virtual ~Base()
 {
  if(NULL==Base::tem_object)
   delete Base::tem_object ;
  Base::tem_object=NULL ;
 }
private:
 /*
 *  暫存加載的對象,對於同一個對象無論LoadObject多少次 加載的永遠只是
 *  返回的同一份內存即同一個對象,直到這個對象的聲明周期完畢,那麼再次加載會是不同的對象
 */
  static Base *tem_object;
};
Base * Base::tem_object=NULL ;  //必須初始化靜態指針
//序列化類Data
class Data  :public Base
{   
private :
 int data ;
public:
    Data(int x)
    {
 cout<<"Data構造中..."<<endl ;
 this->data=x;
    }
    void OutPut()
    {
     cout<<"Data.data="<<this->data<<endl ;
    }
} ;
//序列化類MyObject
class MyObject :public Base
{
public :
  MyObject(int x)
  {  
 cout<<"MyObject 構造中.."<<endl;
      this->x=x ;
  }
  ~MyObject()
  {
  }
 
  MyObject ShowX()  //一段最簡單的代碼
 {
  cout<<"x="<<x<<endl ;
  return (*this) ;
 }
private :
 int x ;
}  ;
int main()
{  
    string file1="c:\\data.txt" ;
    string file2="c:\\myobject.txt" ;
 int len1=sizeof(Data) ;
 int len2=sizeof(MyObject) ;
 /*
 *  序列化測試
 */
 //測試對象1 ...
    Data *d=new Data(8);
    Base::StoreObject(d,file1,len1) ;
 //測試對象2
 MyObject *obj=new MyObject(33) ;
 Base::StoreObject(obj,file2,len2) ;  
   
  /*
 *  反序列化測試。。
 */
 ((Data*)Base::LoadObject(file1,len1))->OutPut() ;
 ((MyObject*)Base::LoadObject(file2,len2))->ShowX()  ;

 delete d ;
 delete obj ;
 return 0 ;
}
操蛋的是睡覺之前出BUG了 ,明天要帶著BUG裸考了 。。
BUG1    同時序列化 2個以上的對象  如果序列化和反序列化放在一起了 就像下面的代碼
   Data *d=new Data(43);
    Base::StoreObject(d,file1,len1) ;
  MyObject *obj=new MyObject(13) ;
 Base::StoreObject(obj,file2,len2) ;
 ((Data*)Base::LoadObject(file1,len1))->OutPut() ;
 ((MyObject*)Base::LoadObject(file2,len2))->ShowX()  ;  
發現Data類的域中的x的值居然和MyObject類的成員數據是一樣的 。。。 但是如果像下面這樣一次處理一個 就不會有問題  。
  Data *d=new Data(43);
    Base::StoreObject(d,file1,len1) ;
 ((Data*)Base::LoadObject(file1,len1))->OutPut() ;
BUG2     如果先調用如下
  Data *d=new Data(43);
    Base::StoreObject(d,file1,len1) ;
然後把上述代碼注釋掉,在調用如下,在從文件加載 就會出現值的亂碼 
 ((Data*)Base::LoadObject(file1,len1))->OutPut() ;
相反的 如果一次性把序列化和反序列化寫在一起 ,那麼即使下次調用多次也不會出問題,,,
算了考完試再繼續Debug吧...哪位願意幫忙調試下。。。
\

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved