¿Cómo deserializar clases polimórficas?
Tengo una clase base abstracta llamada User
, de la que heredan Student
y Professor
. User
tiene funciones virtuales para escribir en un archivo (serialización) que son sobreescritas en las clases derivadas.
void Student::write(std::ofstream& ofs) const {
ofs << typeid(*this).raw_name() << id << "," << get_name() << "," << get_surname() << ",";
}
void Professor::write(std::ofstream& ofs) const {
ofs << typeid(*this).raw_name() << title << "," << get_name() << "," << get_surname() << ",";
}
También tiene una función para leer desde un archivo (deserialización). El problema es que, cuando leo typeid(*this).raw_name()
desde el archivo, no sé cómo acceder a Student
o Professor
para poder instanciar uno de ellos. Estoy usando una clase de estructura de datos de plantilla, por lo que no puedo verificar eso explícitamente.
“`cpp
template <typename t="">
class UndirectedGraph {
…
<pre><code>void for_each_DFS(int vertex, const std::function<void(const t&)="">& func) const {
for (const auto value : *nodes.at(vertex))
func(value);
}
void for_each_DFS(int vertex, const std::function<void(t&)>& func) {
for (auto value : *nodes[vertex])
func(value);
}
virtual void write(std::ofstream& ofs) const override {
if (std::is_pointer<t>::value)
for_each_DFS(0, [&ofs](const T& obj) { ofs << *obj; });
else
for_each_DFS(0, [&ofs](const T& obj) { ofs << obj; });
}
virtual void read(std::ifstream& ifs) override {
std::string type;
for_each_DFS(0, [&ifs](T& obj) {
// aquí obtengo esa información, pero ¿cómo la uso para declarar el tipo de la clase derivada?
std::getline(ifs, type, ',');
ifs >> obj;
});
}
</code></pre>
}
“`</void(t&)></void(const>
davy.ai
Para resolver este problema, podrías agregar una función virtual en la clase base
Usuario
que devuelva un identificador único para cada clase derivada. Por ejemplo:Luego, en cada clase derivada, puedes implementar esta función para devolver una cadena única, como:
Ahora, cuando lees
typeid(*this).raw_name()
desde un archivo en la funciónleer
de la claseGrafoNoDirigido
, puedes compararlo con los identificadores únicos devueltos por la funciónobtener_tipo()
para determinar el tipo de la clase derivada. Por ejemplo:De esta manera, puedes asignar dinámicamente objetos del tipo correcto y deserializarlos desde un archivo sin tener que depender de la función
typeid
.