Сохранение и загрузка данных в файл c++ (новичок)

У меня есть класс, содержащий много разных переменных, например, там есть несколько многомерных векторов.

Я слышал, что вы можете хранить и загружать данные непосредственно в файл, но до какой степени?

Например, если я создам экземпляр этого класса, заполню его, а затем сохраню в файл, смогу ли я загрузить его таким же образом? Например, как это работает? Я просто сохраняю все это за один раз или мне нужно как-то разделить данные?


person Sebastian Zander    schedule 06.07.2012    source источник
comment
Вам нужно преобразовать ваши данные в и из последовательности байтов. Почитайте про сериализацию.   -  person aschepler    schedule 06.07.2012
comment
Вы ищете сериализацию и десериализацию. Какой фреймворк вы используете или это чистый STL?   -  person 0xC0000022L    schedule 06.07.2012


Ответы (3)


Это не совсем тема для начинающих в С++

C++ не имеет автоматизированного способа хранения/загрузки ваших объектов в/из файла. В любом случае, вы решили пойти, вам придется реализовать его самостоятельно.

Вы можете перегрузить операторы << и >> для использования с потоками или использовать свои собственные методы Load и Store (или любые другие имена, которые вы выбрали, например, Serialize / Deserialize). Я лично предпочитаю создавать свои собственные функции и не использовать операторы, но это только я.

Вот простой пример (с перегруженными операторами << и >>):

#include <fstream>
#include <iostream>

using namespace std;

class MyClass
{
public:
    MyClass (int x) : m_x(x), m_y(x+1) {}

    friend istream& operator >> (istream& in, MyClass& obj);
    friend ostream& operator << (ostream& out, const MyClass& obj);

private:
    int m_x;
    int m_y;
};

istream& operator >> (istream& in, MyClass& obj)
{
    in >> obj.m_x;
    in >> obj.m_y;
    return in;
}

ostream& operator << (ostream& out, const MyClass& obj)
{
    out << obj.m_x << ' ';
    out << obj.m_y << endl;
    return out;
}

int main(int argc, char* argv[])
{
    MyClass myObj(10);
    MyClass other(1);
    cout << myObj;
    ofstream outFile ("serialized.txt");
    outFile << myObj;
    outFile.close();
    ifstream inFile ("serialized.txt");
    inFile >> other;
    inFile.close();
    cout << other;
    return 0;
}

Стоит отметить, что вы должны позаботиться о формате сериализации. В приведенном выше примере это просто текст; но если вы собираетесь хранить много этих объектов, вы можете начать думать о сериализации двоичных данных (вам нужно будет использовать флаги ofstream::binary и ifstream:binary при открытии файлов, и вам не понадобятся дополнительные разделители, такие как ' ' и endl в вашем файле). поток сериализации).

Обычно, когда вы думаете о сериализации, вы также хотите думать об управлении версиями вашего потока — и это отдельная тема.

person Peter Al    schedule 06.07.2012

Вы можете рассмотреть возможность реализации операторов потока.

С ними вы можете просто использовать следующее для чтения и записи:

fileStream >> yourObject
fileStream << yourObject 

В основном в операторе >> вы будете читать поток и создавать объект с найденными данными. В операторе ‹‹ вы записываете объект в поток в том же формате, в котором вы ожидаете его прочитать.

Используя этот способ работы, вы можете сериализовать любой объект, который у вас есть.

Поищите в Google «операторы потока перегрузки», чтобы узнать, как реализовать эти операторы.

person W. Goeman    schedule 06.07.2012
comment
Я тоже так делаю. У меня есть структура сериализации, которая перегружает одни и те же операторы. Я уверен, что некоторые скажут — не изобретайте велосипед, а просто используйте ускорение или что-то в этом роде. Мне нравится контролировать код, который делает что-то столь фундаментальное. - person Rafael Baptista; 06.07.2012

Вы можете либо предоставить код, который будет выполнять итерацию по всем членам класса (при желании пропуская второстепенные и преобразовывая некоторые другие), либо подготовить непрерывный поток данных. Это сериализация в более узком смысле. То же самое нужно делать в обратном порядке при чтении.

В C++ вы также можете выполнить двоичный дамп, например CopyMemory(ptr, sizeof(*ptr). Это может работать только в том случае, если ваши данные не содержат указателей (особенно это касается скрытых указателей для классов с виртуальными методами). Его единственные плюсы — простота и огромная скорость. Этот подход требует, чтобы ваши данные были непрерывными в памяти, что иногда полезно само по себе.

person Agent_L    schedule 06.07.2012