#include <iostream>
#include <string>

struct base {
   virtual ~base( ) = default;               // dynamic_cast requiere que exista la tabla virtual, por lo que necesitamos al menos una función virtual
};

struct derivado1 : base {
   int n = 5;
};

struct derivado2 : base {
   std::string s = "hola";
};

int main( ) {
   derivado1 d1;
   derivado2 d2;
   base* arr[3] = { nullptr, &d1, &d2 };     // el elemento extra al inicio es para que d1 esté en el indice 1 y d2 esté en el índice 2

   int opcion;                               // pedir un índice (1 para d1, 2 para d2)
   std::cin >> opcion;
   base* p = arr[opcion];

   // ¿qué tenemos en la mano? dynamic_cast puede revisar
   derivado1* checar1 = dynamic_cast<derivado1*>(p);     // ¿será un derivado1?
   if (checar1 != nullptr) {                             // válido si sí, nulo si no
      std::cout << checar1->n << "\n";
   }

   derivado2* checar2 = dynamic_cast<derivado2*>(p);     // ¿será un derivado2?
   if (checar2 != nullptr) {                             // válido si sí, nulo si no
      std::cout << checar2->s << "\n";
   }
}
