簡體   English   中英

將向量的內容作為二進制數據寫入文件

[英]Writing contents of vector to file as binary data

我有一些15歲的C ++代碼,我試圖將其帶入更現代的時代。 在此階段,我嘗試獲取使用Visual C ++ 6.0編譯的代碼,現在可以使用VS 2003進行編譯(Microsoft Visual C ++ .NET 69462-335-0000007-18915)。

std::vector<myClassType> myVect;
...

// Assuming vector.begin() simply points to start of a contiguous array
bool OK = File.write((char*) myVect.begin(),
                     myVect.size() * sizeof(myClassType));

當我閱讀評論時,我會擔心……我們真的可以假設向量在連續的內存中嗎? 如果沒有,什么是更好的方法? 我是否需要遍歷向量內容並寫入myClassType中的每組數據?

實際上,編譯器總是抱怨將begin()的結果強制轉換為char *。

確保將std::vector的元素存儲在連續的內存中,因此,只要myClassTypePOD類型 ,則您可以嘗試執行此myClassType 否則,您將不得不遍歷std::vector將每個元素序列化為一個平面格式(根據需要)。

但是, std::vector::begin()方法將返回第一個元素的迭代器 ,而不是指向元素數據的指針 迭代器就像一個指針,但不是指針。 容器實現被允許使用實際的指針作為迭代器,但是它們使用包裝器類的次數更多。 不要依靠這種行為! 以預期的方式使用迭代器API,並且不要假定迭代器是實際的指針。

要獲得指向向量的第一個元素的數據的有效指針,您需要執行以下任一操作:

  1. 使用std::vector::data() (僅C ++ 11和更高版本):

     myVect.data() 

    即使向量為空,也可以安全使用。 size()為0時data()可能會或可能不會返回nullptr ,但這是可以的,因為當size()為0時write()不會嘗試訪問任何內存。

     bool OK = File.write((char*) myVect.data(), myVect.size() * sizeof(myClassType)); 
  2. 使用std::vector::operator[]獲取對第一個元素的引用,然后使用operator&獲取元素的地址:

     &myVect[0] 

    請注意, operator[]不執行邊界檢查,因此如果指定的索引為> = size() ,則將返回未定義的指針,因此請確保在寫入向量之前檢查向量是否為空:

     bool OK = myVect.empty() || File.write((char*) &myVect[0], myVect.size() * sizeof(myClassType)); 
  3. 與#2相同,但使用std::vector::front()代替:

     &myVect.front() 

    請注意,在空向量上調用front()是未定義的行為,因此請確保檢查向量是否為空:

     bool OK = myVect.empty() || File.write((char*) &myVect.front(), myVect.size() * sizeof(myClassType)); 
  4. 使用begin()獲取第一個元素的迭代器,然后使用operator*解引用迭代器以獲取對其指向的元素的引用,然后可以獲取元素的地址:

     &(*(myVect.begin())) 

    請注意,當向量為空時, begin()返回end()迭代器,並且取消引用end()迭代器是未定義的行為,因此請確保檢查向量是否為空:

     bool OK = myVect.empty() || File.write((char*) &(*(myVect.begin())), myVect.size() * sizeof(myClassType)); 

雷米·勒博的答案是正確的。 要添加它,如果您想增加代碼的安全性,還應該使用static_assert來確保myClassType可以安全編寫,如您所願:

#include <type_traits>
static_assert(std::is_pod_v<myClassType>, "myClassType is potentialy unsafe to write as-is");

如果以后有人以不安全的方式修改myClassType使其無法在File.write()代碼中使用,則此編譯時檢查將捕獲它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM