1

我正在尝试创建一个通用类来向文件写入和读取对象。称之为 ActiveRecord 类

只有一种方法,可以保存类本身:

void ActiveRecord::saveRecord(){
 string fileName = "data.dat";

 ofstream stream(fileName.c_str(), ios::out);
 if (!stream) {
  cerr << "Error opening file: " << fileName << endl;
  exit(1);
 }
 stream.write(reinterpret_cast<const char *> (this), sizeof(ActiveRecord));
 stream.close();
}

现在我用 User 类扩展这个类:

class User : public ActiveRecord
{
 public:
  User(void);
  ~User(void);
  string name;
  string lastName;
};

创建和保存用户我想做类似的事情:

User user = User();
user.name = "John";
user.lastName = "Smith"
user.save();

如何让这个 ActiveRecord::saveRecord() 方法获取任何对象和类定义,以便它写入我发送的任何内容:

看起来像:

void ActiveRecord::saveRecord(foo_instance, FooClass){
 string fileName = "data.dat";

 ofstream stream(fileName.c_str(), ios::out);
 if (!stream) {
  cerr << "Error opening file: " << fileName << endl;
  exit(1);
 }
 stream.write(reinterpret_cast<const char *> (foo_instance), sizeof(FooClass));
 stream.close();
}

当我们讨论它时,c++ 中默认的 Object 类型是什么。例如。在objective-c中它的id在java中它是AS3中的对象它是对象在C++中它是什么?

4

2 回答 2

5
stream.write(reinterpret_cast<const char *> (foo_instance), sizeof(FooClass));

这行不通。 string在堆上分配其数据(IIRC,当它大于 16chars 时)。您的重新解释转换将不包括该堆数据。

不要重新发明轮子,这是一个不平凡但已解决的问题。使用Google Protocol Buffers、XML 或boost 序列化库

您想到的是模板,但您不能“只序列化任何对象”,因为在 POD(普通旧数据)类型之外,它们的表示并不明显。

此外,sizeof(BaseClass)与 User 子类一起使用将不起作用。它会将子类的成员数据从演员表中切出,而不是将其放入文件中。

并且没有“C++ 中的默认对象类型”。

于 2010-05-23T02:58:08.847 回答
1

您提出的建议不会进行深度序列化,您通常无法知道该对象持有什么样的资源。
要让它存储任何对象,您将使用模板函数并将实际存储委托给相关类或其朋友(即operator<<()):

template<class T> void ActiveRecord::saveRecord(const T& foo) {
    // ...
    stream << foo;
    // ...
}

为此,您需要operator<<()为相关类提供重载:

class Foo {
    friend std::ostream& operator<<(std::ostream&, const Foo&);
    // ...
    int a, b;
    // ...
};

std::ostream& operator<<(std::ostream& o, const Foo& f) {
    o << f.a << f.b;
    // ...
    return o;
}

但正如斯蒂芬所说,为什么不使用经过验证的序列化解决方案而不是自己滚动?

于 2010-05-23T03:07:56.637 回答