【发布时间】:2017-01-21 23:30:03
【问题描述】:
此代码有效,但正确的做法是什么?
我的意思是,如何消除 read_in 函数中的 switch 语句,或者处理动物类或其子类中的所有读取,以便我的 read_in 函数可以像我的 write_out 函数一样简单?
我有一个vector<animal*> *animals,里面装满了猫和普通动物,我需要在文件中写入/读取。
我省略了一些代码,所以帖子不会太大...
enum class animal_type
{
GENERIC_ANIMAL,
CAT
};
假设我有一个班级动物
class animal
{
animal_type m_type;
string m_name;
virtual void write_binary(ofstream &out)
{
out.write((char*)(&m_type), sizeof(m_type)); //first 'animal_type'
out.write((char*)(&m_type), sizeof(m_type)); //second 'animal_type'
out.write(m_name.c_str(), m_name.size()+1);
{
virtual void read_binary(std::ifstream &in)
{
in.read((char*)(&m_type), sizeof(m_type)); //read the second animal type here
m_name = read_null_string(in);//this function returns next string from input
}
};
还有一个派生自动物的类
class cat : public animal
{
bool m_is_cute;
void write_binary(std::ofstream &out)
{
animal::write_binary(out);
out.write((char*)(&m_is_cute), sizeof(m_is_cute));
}
void read_binary(std::ifstream &in)
{
animal::read_binary(in);
in.read((char*)(&m_is_cute), sizeof(m_is_cute));
}
};
我将它们写入这样的文件
void write_out(std::ofstream &out, std::vector<animal*> *animals)
{
int size = animals->size();
out.write((char*)(&size), sizeof(size));
for(animal* a : *animals)
{
a->write_binary(out);
}
}
然后像这样从文件中读取它们
void read_in(std::ifstream &in, std::vector<animal*> *animals)
{
animals->clear();
int size;
in.read((char*)(&size), sizeof(size));
for(int i = 0; i< size; ++i)
{
animal_type type;
//read the first 'animal_type' here
in.read((char*)(&type), sizeof(type));
animal *a;
switch(type)
{
case(animal_type::GENERIC_ANIMAL):
a = new animal(in);//this constructor just calls the read_binary method
break;
case(animal_type::CAT):
a = new cat(in);//this constructor just calls the read_binary method
break;
}
animals->push_back(a);
}
}
【问题讨论】:
-
考虑使用
serialization/de-serialization -
你可以看看Boost serialization。
-
离题:更喜欢
animals的引用而不是此处的指针:void read_in(std::ifstream &in, std::vector<animal*> *animals)。除其他外,引用可防止您意外传入虚假指针。必须存在参考(否则您必须玩明显和愚蠢的选角游戏)
标签: c++ inheritance serialization