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>向量列表中?

任何例子都会有很大帮助。

4

1 回答 1

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";
}
于 2013-11-01T15:57:18.733 回答