C++ is (mostly) statically typed. That is, the types of variables have to be known at compile time and cannot change at runtime, e.g. depending on some user input.
The one exception to this rule are polymorphic classes: When you have a base class with some virtual
member function, then there will be a way (most likely a pointer as a member of all instances of that class) to distinguish between sub classes of that class (and itself):
struct Base {
virtual ~Base() {}
};
struct SubA : public Base {};
struct SubB : public Base {};
// ...
Base const & instance = SubA{};
try {
SubA const & as_subA = dynamic_cast<SubA const &>(instance);
// The instance is a SubA, so the code following here will be run.
} catch (std::bad_cast const &) { /* handle that somehow */ }
Using this mechanism, or preferably the virtual function itself, you can have different behavior depending on the dynamic type of an instance, which is only known at run time.
C++ being a flexible language, you can - of course - also implement something similar on your own:
struct Thing {
enum class Type {
Integer, String, Vector
} type;
union {
int integer;
std::string string;
std::vector<int> vector;
} data;
// Plus a lot of work in constructors, destructor and assignment, see rule of 5
};
Using something like this allows you to have objects with a "type" of dynamic nature, and are able to do different things depending on what type the object actually has at run time.
But of course you don't need to write that on your own (though its not that hard), there are a lot of implementations like for example boost::any
and boost::variant
.