還有的一點從文件---->內存--------->對象的恢復 沒有構造函數的調用 ,這一點很神奇 。。。
我們成功的恢復了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吧...哪位願意幫忙調試下。。。