2014-02-10 53 views
0

我有一個指向基類對象的向量,所以我可以管理從該類派生的對象。保存指向文件的矢量對象

vector <Product*> products; 

我試圖同時通過矢量 迭代這些對象寫入文件,但我不知道這是否正常工作。

void Inventory :: saveProductsToFile() 
{ 
    ofstream outfile; 
    outfile.open("inventory.dat",ios::binary); 

    list <Product*> :: iterator it; 
    for(it=products.begin(); it!=products.end(); it++) 
     outfile.write((char*)*(it),sizeof(Product)); 
} 

的文件被創建,但我如果我很節約的實際對象本身或其 addresses.Is這是正確的或有另一種方式不知道?

這是文件的樣子:

ˆFG " H*c  \Âõ(œ@@pFG h*c b'v  [email protected] 
+0

你能告訴我們這個函數被調用後的文件看起來像什麼嗎? –

+0

派生類可能具有不同的大小,所以這不起作用。另外,如果有任何動態分配或包含動態分配內存的成員(如'std :: string'),它也將無法工作。 – hmjd

+0

改爲使用'sizeof(* it)';是的,正如hmjd提到的,如果你的類包含指針,它們必須在串行化之前調試 – Paranaix

回答

0

那不是你「連載」數據的方式。像這樣,指針只在運行時期間有效,或者直到你刪除它們(取決於發生什麼/停止)。像這樣,你將無法恢復你的數據,因爲在程序停止後,你以前的內存中的所有內容都將失效。你將不得不存儲你班級的實際值。

+0

這是我試圖存儲的實際值,而不是指針。我第一次使用迭代器和向量,並不確定特定的「寫入」命令保存到文件的內容。 – Spapo

+0

然後,您需要獲取實際值並將其提供給您的物流對象。我很驚訝它甚至可以像這樣工作,因爲它好像將對象值從Product轉換爲const char指針。 –

+0

會像'outfile << (*it)-> getCode();'然後呢?我的數據可以恢復嗎? – Spapo

1

你的代碼可以工作。你不能以這種方式序列化 中的多態對象。對於初學者,您正在向磁盤寫入隱藏的vptr列出 ;當您重新讀取數據時,它將無效。而 您只寫出基類(Product), 中的數據,因爲這是sizeof(Product)的計算結果。最後,只寫一個除了char[] 之外的任何字節圖像都可能意味着你將來無法在一段時間內重新讀取數據 (在編譯器升級或機器升級後,或者其他任何情況下) 。

,你所要做的就是定義(二進制或文本)的格式爲 文件,並編寫。對於基本類型,您可以使用XDR或協議緩衝區等存在的東西來啓動 ,但這兩種方法都不能很好地適用於多態類型。對於 多態類型,您必須首先定義 在重新讀取時如何識別有問題的類型。這可能是 棘手:沒有什麼在std::type_info,幫助,所以你需要 建立您的 (派生)類型和標識符之間的關係的一些手段。然後,每個派生類 必須實現一個write函數,該函數首先寫入其類型,然後將其數據寫入一個元素。讀取時,您讀取該類型,在地圖中查找相應的 類型的讀取函數,然後調用該函數,然後逐個讀取數據 。

最後,我可能會指出,我已經看到了成功的系列化 方案取決於生成的代碼。你可以在一個單獨的文件或特殊的標記(特別是在C++中的標註註釋 )中描述你的 類型,並且有一個程序讀取 並生成必要的代碼(通常使用實際的類 ) 。

+0

我會在之前給出標識符方法,看看映射如何進行!謝謝你的時間。 – Spapo