我正在尝试创建一个通用类来编写和从文件中读取对象。 称之为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 ++中的默认对象类型是什么。 例如。 在objective-c中它是id 在java中它是Object 在AS3中它是对象 什么是C ++ ??
答案 0 :(得分:5)
stream.write(reinterpret_cast<const char *> (foo_instance), sizeof(FooClass));
这不起作用。 string
在堆上分配数据(IIRC,当它大于16chars时)。您的重新解释转换将不包括该堆数据。
不要重新发明轮子,这是一个非常重要但解决的问题。使用Google Protocol Buffers,XML或boost serialization library。
你所想到的是模板,但你不能“只是序列化任何对象”,因为在POD(普通旧数据)类型之外,它们的表示并不明显。
此外,将sizeof(BaseClass)
与User子类一起使用将不起作用。它会将子类的成员数据从转换中切除,而不是将其放在文件中。
并且没有“c ++中的默认对象类型”。
答案 1 :(得分: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;
}
但正如斯蒂芬所说,为什么不使用经过验证的解决方案进行序列化而不是自己动手?