Ali*_*232 4 c++ polymorphism vtable
我正在将一些对象复制到一个文件中,并且它们都是从同一个类中删除的.但我希望能够在加载它们之后调用它们的函数来执行该类应该执行的操作,这是我迄今为止所做的:
#include <iostream>
#include <fstream>
using namespace std;
struct a
{
virtual void print()
{
cout << "this is a.\n";
};
};
struct b : public a
{
virtual void print()
{
cout << "this is b.\n";
}
};
int main()
{
ofstream testofile("test.bin",ios::binary);
a* tempa = new a;
a* tempb = new b;
testofile.write((char*)tempa,sizeof(a));
testofile.write((char*)tempb,sizeof(b));
testofile.flush();
testofile.close();
ifstream testifile("test.bin",ios::binary);
a* x = (a*)new char[max(sizeof(a),sizeof(b))];
testifile.read((char*)x,sizeof(a));
x->print();
testifile.read((char*)x,sizeof(b));
x->print();
}
Run Code Online (Sandbox Code Playgroud)
我的例子工作正常,但如果我评论保存部分然后运行该程序似乎vtable对新的已修改的应用程序无效(虽然我的代码中的任何内容都没有更改).问题是我的文件管理器类不知道可能从我的基础对象中解脱的所有可能的对象,我想只使用一次调用文件管理器来重建我的所有应用程序结构来加载它.当然,我的每个对象都有自己的保存/加载功能,但是filemanager应该如何猜测适合当前数据块的加载函数在哪里?
请不要这样做.决不.
基本上,你做的是使用旧式铸铁投下a*的char*.这在两个不相关的类型之间静默地产生reinterpret_cast,并且高度依赖于实现.您不能依赖底层内存布局:它可能因任何原因而改变(即使使用相同的编译器).
如果您的类包含指针,则无法保证在重新加载类时,它们指向的数据仍然存在(或者只是相同).
如果你想提供一个序列化机制,创建你自己的serialize()和deserialize()函数(它们甚至可以是你可以专门化的模板化函数,或者只是常规的成员函数,它并不重要).
当然,这需要更多的工作,但为了可靠性.此外,这样做,您可以优化数据表示以适应任何存储类型(保存到磁盘,发送到网络,...),您甚至可以更改类接口,并仍然保持与已经序列化的实例的兼容性.
| 归档时间: |
|
| 查看次数: |
157 次 |
| 最近记录: |