新手指南 序列化篇之二

2021-04-16 12:29:52 字數 3133 閱讀 8535

序列化初步(翻譯)

原著:http://www.codeproject.com/cpp/serialization_primer2.asp

在第一部分,我們學到了如何通過carchive

類的serialize()

函式來序列化乙個簡單物件。象下面的程式這樣:

int cfoo::serialize

(carchive* parchive)

else

}catch_all (pexception)

end_catch_all

return (nstatus);

}這段**有乙個問題,如果我們錯誤的從資料檔案中去讀取並不存在的資訊會怎麼樣?如果資料檔案中在

cstring

之後不是乙個整數,那麼

serialize()

函式將返回

error

。這也不錯,但是如果我們可以給錯誤定位,並返回乙個更加詳細的錯誤資訊,比如

invalid_datafile

,那就更好了。我們可以通過物件簽名來確認我們是在讀取乙個有效的資料檔案。

物件簽名

物件簽名就是用乙個字串來識別乙個物件。我們修改

cfoo

類的定義來增加乙個簽名:

class cfoo

;簽名在

foo.cpp

中申明:

// static constants

const cstring cfoo::signature = "fooobject";

下一步,我們修改

serialize()

函式,在序列化物件的資料成員前先序列化這個簽名。如果遇到無效的簽名,或者簽名丟失,那麼可以認為我們在試圖讀取乙個並不包含有

cfoo

物件的資料儲存。以下是讀取有簽名的物件的流程:

以下是流程實現**:

int cfoo::serialize

(carchive* parchive)

else

// read employee name and id

(*parchive) >> m_strname;

(*parchive) >> m_nid;}}

catch_all (pexception)

end_catch_all

return (nstatus);

}你必須確保你所有的物件都有唯一的簽名。具體的簽名內容並不重要。如果你正在開發一批產品,那麼在公司範圍內增加乙個物件簽名註冊步驟是非常有幫助的。另一方面,開發者將不會給不同的物件使用相同的簽名。如果你想讓你的資料檔案更難以被反解,那麼你應該使用乙個與物件名稱沒有明顯任何關係的簽名。

版本

如果你在產品的生命週期內進行公升級,那麼你也許要通過增加或者刪除資料成員來修改

cfoo

類結構。如果你只是為

cfoo

發布新的版本,並且試圖從資料儲存中讀取舊版本的物件,那麼將會失敗。這明顯是不可以接受的。

cfoo

的任何版本都應該可以讓乙個更舊版本恢復。

換句話說,

cfoo

的序列化方法應該是向前相容的。這個問題通過給物件增加版本是很容易完成的。與給物件增加簽名相同,我們增加乙個整數常量來指定這個物件的版本號。

class cfoo

;物件的版本號在

foo.cpp

中申明

// static constants

const cstring cfoo::signature = "fooobject";

const intcfoo::version = 1;

下一步,我們修改

serialize()

函式,在序列化簽名之後,序列化物件的資料成員之前序列化版本。如果遇到更新的版本,我們試圖讀取乙個物件不支援的版本,那麼,在下面的例子中,我們就返回乙個狀態標誌

unsupported_version

。 int cfoo::serialize

(carchive* parchive)

else

// read version - complain if unsupported

int nversion;

(*parchive) >> nversion;

bversionread = true;

if (nversion > getversion())

// read employee name and id

(*parchive) >> m_strname;

(*parchive) >> m_nid;}}

catch_all (pexception)

end_catch_all

return (nstatus);

}cfoo

的版本1

包含兩個資料成員:乙個

cstring

型別(m_strname)

和乙個int

型別(m_nid)

。如果我們在版本

2中增加第三個成員

(例如:

int m_ndept)

。那麼我們必須決定,當讀取乙個舊版本時,

m_ndept

應該初始化為多少。在下面的例子中,我們初始化

m_ndept為1

,意味著這個職員的部門為「未知」。

class cfoo

;我們需要將

foo.cpp

中物件的版本號改為2。

const int cfoo::version = 2;

最後,我們修改

serialize()

函式中讀取物件的部分,如果我們讀取的是乙個舊版本的資料檔案,將

m_ndept

初始化為

-1。注意,檔案儲存總是用最新的版本。

int cfoo::serialize

(carchive* parchive)

else

else

}}

catch_all (pexception)

end_catch_all

return (nstatus);

}

新手指南 序列化篇之二

序列化初步 翻譯 原著 http www.codeproject.com cpp serialization primer2.asp 在第一部分,我們學到了如何通過carchive 類的serialize 函式來序列化乙個簡單物件。象下面的程式這樣 int cfoo serialize carchi...

新手指南 序列化篇之二

序列化初步 翻譯 原著 http www.codeproject.com cpp serialization primer2.asp 在第一部分,我們學到了如何通過carchive 類的serialize 函式來序列化乙個簡單物件。象下面的程式這樣 int cfoo serialize carchi...

新手指南 序列化篇之二

序列化初步 翻譯 原著 http www.codeproject.com cpp serialization primer2.asp 在第一部分,我們學到了如何通過carchive 類的serialize 函式來序列化乙個簡單物件。象下面的程式這樣 int cfoo serialize carchi...