假设以下代码:
// 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 :(得分:2)
您需要为对象提供某种形式的序列化。这是一个非常简单的例子(不包括错误检查,类型构造等)。
此示例显示了最原始的序列化类型,但它足以提供您需要执行的操作的示例。
当你开始处理派生类时,它会变得更加棘手,因为你需要一些工厂方法来根据你序列化的一些sentinel值来正确地创建类型。
#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";
}