将数据保存和加载到文件 C++(初学者)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11365456/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:04:52  来源:igfitidea点击:

Saving and loading data to a file c++ (beginner)

c++loadingsave

提问by Sebastian Zander

I have a class containing many different variables, for example there's a few multidimensional vectors in there.

我有一个包含许多不同变量的类,例如那里有一些多维向量。

I've heard that you can store and load data directly to a file, but to what extent?

我听说您可以将数据直接存储和加载到文件中,但是到什么程度呢?

For example if I create an instance of this class, fill it up, then save it to a file, can I load it the same way? Like how does that work? Do I just save it all in one go or do I have to split up the data somehow?

例如,如果我创建这个类的一个实例,填充它,然后将它保存到一个文件中,我可以用同样的方式加载它吗?就像它是如何工作的?我是一次性保存所有数据还是必须以某种方式拆分数据?

回答by Peter Al

This is not exactly beginner's topic in C++

这不是 C++ 初学者的主题

C++ has no automated way to store / load your objects to / from a file. Either way you chose to go, you'll have to implement it yourself.

C++ 没有自动的方式来存储/加载您的对象到/从文件。无论您选择采用哪种方式,都必须自己实施。

You might chose to overload the <<an >>operators to use with streams, or you might want to go with your own Loadand Storemethods (or whatever names you chose appropriate, like, Serialize/ Deserialize). I personally prefer to create my own functions and not to use the operators, but it's just me.

您可能选择重载<<an>>运算符以与流一起使用,或者您可能想要使用自己的LoadandStore方法(或您选择的任何适当名称,例如Serialize/ Deserialize)。我个人更喜欢创建自己的函数而不是使用运算符,但这只是我自己。

Here is a simple example (with overloaded <<and >>operators):

这是一个简单的示例(带有重载<<>>运算符):

#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;
}

It worth to mention that you should take care about the serialization format. In the example above it's just text; but if you are going to store a lot of those objects, you might start thinking about serializing binary data (you'll need to use ofstream::binaryand ifstream:binaryflags while opening the files, and will not need additional separators, like ' 'and endlin your serialization stream).

值得一提的是,您应该注意序列化格式。在上面的例子中,它只是文本;但如果你要存储大量的对象,你可能开始对串行二进制数据思(你需要使用ofstream::binaryifstream:binary标志,同时打开的文件,也不会需要额外的分隔符,就像' 'endl你的序列化流)。

Typically, when you think of serialization, you also want to think of the versioning of your stream -- and this is another separate topic.

通常,当您考虑序列化时,您还想考虑流的版本控制——这是另一个单独的主题。

回答by W. Goeman

You could consider implementing stream operators.

您可以考虑实现流运算符。

With these you could simply use the following to read and write:

有了这些,您可以简单地使用以下内容进行读写:

fileStream >> yourObject
fileStream << yourObject 

Basically in the >> operator, you will read the stream and construct the the object with the found data. In the << operator, you write the object to the stream in the same format as you expect to read it.

基本上在 >> 运算符中,您将读取流并使用找到的数据构造对象。在<< 操作符中,您将对象以与您期望读取的格式相同的格式写入流。

Using this way of working, you can serialize any object you have.

使用这种工作方式,您可以序列化您拥有的任何对象。

Google for "overload stream operators" to know how to implement these operators.

谷歌搜索“重载流操作符”以了解如何实现这些操作符。

回答by Agent_L

You can either provide a code that will iterate through all members of a class (optionally skipping the non-important ones and converting some others) and prepare continuous stream of data. That's serialization in the narrower sense. Ofc the same thing needs to be done in reverse when reading.

您可以提供一个代码来遍历类的所有成员(可以选择跳过不重要的成员并转换其他成员)并准备连续的数据流。这是狭义上的序列化。Ofc在阅读时需要反过来做同样的事情。

In C++ you can also perform a binary dump, like CopyMemory(ptr, sizeof(*ptr). It can only work if your data contain no pointers (that especially includes hidden pointer for classes with virtual methods). Its only upsides are simplicity and tremendous speed. This approach requires your data to be contiguous in memory what sometimes is beneficial on it's own.

在 C++ 中,您还可以执行二进制转储,例如CopyMemory(ptr, sizeof(*ptr). 它只有在您的数据不包含指针时才能工作(尤其是包含具有虚拟方法的类的隐藏指针)。它唯一的优点是简单和极快的速度。这种方法要求您的数据在内存中是连续的,有时这本身就是有益的。