I have an abstract class Object, which looks like this:
class Object
{
public:
Object();
virtual void DoSomething() = 0;
virtual void Save(std::ofstream &file) = 0;
virtual void Load(std::ifstream &file) = 0;
};
I also have classes Ball and TextBox:
class Ball : public Object
{
public:
Ball(int x, int y, int z)
{
m_x = x; m_y = y; m_z = z;
}
void DoSomething()
{
std::cout << m_x << ", " << m_y << ", " << m_z << std::endl;
}
void Save(std::ofstream &file)
{
file << m_x << " " << m_y << " " << m_z << std::endl;
}
void Load(std::ifstream &file)
{
file >> m_x >> m_y >> m_z;
}
private:
int m_x, m_y, m_z;
};
class TextBox: public Object
{
public:
TextBox(std::string message)
{
m_message = message;
}
void DoSomething()
{
std::cout << m_message << std::endl;
}
void Save(std::ofstream &file)
{
file << m_message << std::endl;
}
void Load(std::ifstream &file)
{
file >> m_message;
}
private:
std::string m_message;
};
I have a vector of pointers to theese objects:
std::vector<Object*> objects;
objects.push_back(new Ball(1, 2, 3));
objects.push_back(new TextBox("Hello world!"));
for (Object *o : objects) o->DoSomething();
I want to save this vector to file. This is very easy. I make something like this:
std::ofstream file("foo.txt");
for (Object *o : objects) o->Save(file);
file.close();
Now I want to load this. And here is a problem. How I can specify, which object (Ball or TextBox) I supposed to load? I could use some indexes, like that:
void Ball::Save(std::ofstream &file)
{
file << 1 << " " << m_x << " " << m_y << " " << m_z << std::endl;
}
void TextBox::Save(std::ofstream &file)
{
file << 2 << " " << m_message << std::endl;
}
Then, after reading this index, I know, that this is a Ball or a TextBox.
int index;
Object *o;
file >> index;
switch (index)
{
case 1: o = new Ball(0, 0, 0); break;
case 2: o = new TextBox(""); break;
}
o->Load(file);
objects.push_back(o);
But is there a better way to store this structure? What if I have 100 inheritors of Object? Can I somehow avoid 100-switch case?
These 'indexes' you came up with are usually called 'metadata'. There are other languages, like java, that support reflection for that purpose but in C++ reflection in still under consideration. For that reason, I would suggest implementing sort of an abstract interface that would return information of the exact class of an object.
Furthermore, I would suggest looking at serialization libraries, that could ease the process of saving and reading data. You can try to start with boost: https://www.boost.org/doc/libs/1_73_0/libs/serialization/doc/index.html
I must admit that I used boost serialization a long time ago, but I remember it was quite easy to use.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.