2013-11-01 2 views
0

Пусть следующий код:Сохранение вектора указателей в файл и читать их снова

// Base class 
class Base { 
public: 
    Base(int val) : hi(val) { 
    } 
    virtual void PublicMethod() { /* Do something */} 

private: 
    int hi; 
}; 

// Child class 
class Child : public Base { 
public: 
    Child(int val) : Base(val) { 
    } 
    void PublicMethod() { /* Do something */} 
}; 

// Vector of pointers to prevent slicing 
std::vector<std::shared_ptr<Base>> list; 

(...) // Fill list with mixed data of class Base and Child 

После того, как список заполняется с объектами, я хочу, чтобы сохранить данные в файл. Для этого я попытался следующие:

std::ofstream os("data.txt", std::ios::out); 

int size1 = list.size(); 
os.write((const char*)&size1, sizeof(int)); 
for (auto it = list.begin(); it < list.end(); ++it) { 
    os.write((const char*)(*it), size1 * sizeof(Base)); 
} 
os.close(); 

Однако я не уверен, что это правильно, и считывать данные из файла и, кажется, не работает должным образом. Я боюсь, что когда я сохраняю данные, sizeof(Base) также не работает для своих дочерних объектов, которые могут быть не одного размера.

Даже если это правильно работает, есть ли способы хранения фактических данных в файле и как я могу легко считывать данные из файла и хранить их в списке векторных файлов shared_ptr<Base>?

Любые примеры могли бы помочь.

+0

Очень много не так. Разделение итератора будет получать shared_ptr, а не объект, на который указывает указатель, который он обертывает. Я даже не могу это построить! Даже с объектом вы не можете просто передать его в blob байтов. Вам нужно посмотреть на сериализацию и перегрузить оператор << или предоставить вашим классам метод 'write()', который принимает значение, которое затем записывает их члены. –

+0

Вам необходимо обеспечить правильную сериализацию и десериализацию для ваших типов (http://en.wikipedia.org/wiki/Serialization). – Chad

+0

Это не работает. Вы не можете сохранить указатель в файле, это связано с тем, что адреса действительны только во время выполнения и если вы не освобождаете их от них. вам нужно будет сериализовать данные, а затем записать их в файл. Это означает, что вам нужно сохранить значение, а не адрес. –

ответ

2

Вам необходимо предоставить некоторую форму сериализации для ваших объектов. Вот очень тривиальный пример (который не учитывает проверку ошибок, тип построения и т. Д.)

В этом примере показан самый примитивный тип сериализации, но этого достаточно, чтобы привести пример того, что вам нужно сделать.

Когда вы начинаете заниматься производными классами, это становится более сложным, так как вам понадобится какой-то заводский метод для правильного создания типов, основанный на некотором значении, которое вы сериализуете.

#include <string> 
#include <iostream> 
#include <sstream> 
using namespace std; 

class A 
{ 
public: 
    A() 
     : a_(0) 
    { 
    } 

    A(int a, const string& n) 
     : a_(a), n_(n) 
    { 
    } 

    // a function to write objects to a stream  
    friend ostream& operator<<(ostream& stream, const A& obj); 

    // a function to read objects from a stream 
    friend istream& operator>>(istream& stream, A& obj); 

private: 
    int a_; 
    string n_; 
}; 

ostream& operator<<(ostream& out, const A& obj) 
{ 
    out << obj.a_ << ' ' << obj.n_; 
    return out; 
} 

istream& operator>>(istream& in, A& obj) 
{ 
    in >> obj.a_ >> obj.n_; 
    return in; 
} 


int main() 
{ 
    A one(1, "one"); 
    A also_one; 

    string buffer; 
    stringstream serializer; 

    // write out your source object to a stream and "store it" 
    // here we simply store it in a string  
    serializer << one; 
    buffer = serializer.str(); 

    // using the "stored" value, read the stored values 
    // into an (already constructed) object 
    stringstream deserializer(buffer); 
    serializer >> also_one; 

    // verify the output is the same 
    cout << one << " is the same as " << also_one << "\n"; 
} 
+0

Я имею дело с производными классами. Что вы подразумеваете под «заводским методом»? Можно ли увидеть, какой тип сериализованной строки следует преобразовать, прежде чем преобразовать ее? – Broxzier

Смежные вопросы