【发布时间】:2021-09-05 23:20:31
【问题描述】:
我有一个包含多个子类的超类 Element,我们称它们为 A 和 B。我想重载 >,以便保存和加载我的对象。
class Element
{
public:
Element();
int superProperty;
virtual void write(iostream &out)
{
out << superProperty;
}
virtual void read(iostream &in)
{
in >> superProperty;
}
};
iostream operator<<(iostream &out, const Element &elt)
{
elt.write(out);
return(out);
}
iostream operator>>(iostream &in Element &elt)
{
elt.read(in);
return(in);
}
class A : public Element
{
public:
A();
int subProperty;
void write(iostream &out)
{
Element::write(out);
out << subProperty;
}
void read(iostream &in)
{
Element::read(in);
in >> subProperty;
}
};
class B : public Element
{
public:
B();
double subProperty;
void write(iostream &out)
{
Element::write(out);
out << subProperty;
}
void read(iostream &in)
{
Element::read(in);
in >> subProperty;
}
};
有了这些定义,我可以很容易地写出我的元素文件,每个元素都写成
iostream mystream;
Element e;
...
mystream << e;
我被困的地方是把它们读回来。我希望它看起来像这样:
iostream mystream;
Element *pe;
...
pe = new Element(); // the problem is right here
mystream >> *pe;
但这行不通,因为我不知道我要读取的元素是元素还是 A 或 B。(在我的应用程序中,我从未实际实例化元素。所有对象都是一个的子类。) 我求助于写出一个字符来表示类...
if (dynamic_cast<A>(e))
{
out << 'A';
out << e;
} else if (dynamic_cast<B>(e))
{
out << 'B';
out << e;
}
然后切换/大小写如下:
char t;
Element *pe;
...
in >> t;
switch (t)
{
case 'A':
pe = new A;
break;
case 'B':
pe = new B;
break;
}
in >> *pe;
但它似乎不优雅。
流式传输不同对象的更好方法是什么?
【问题讨论】:
-
我认为这是一种正确的做法。但也许您可能想使用一些序列化框架,该框架可能已经提供了一种注册类型和其他功能(如版本控制)的方法。