#include <iostream>
#include <vector>
#include <typeinfo>
#include <memory>
// Base class for Simulation Models
class SimulationModel {
public:
virtual ~SimulationModel() = default;
virtual std::string solve() const = 0;
virtual std::string info() const { return "Base Simulation Model"; }
};
// Derived class for Euler Solver
class EulerSolver : public SimulationModel {
public:
std::string solve() const override { return "Solving using Euler's method"; }
std::string info() const override { return "Euler Solver"; }
void eulerSpecificMethod() const { std::cout << "Euler-specific method called\n"; }
};
// Derived class for Runge-Kutta Solver
class RK4Solver : public SimulationModel {
public:
std::string solve() const override { return "Solving using Runge-Kutta 4th order method"; }
std::string info() const override { return "RK4 Solver"; }
void rk4SpecificMethod() const { std::cout << "RK4-specific method called\n"; }
};
// Function to demonstrate static_cast
void demonstrateStaticCast(const SimulationModel* model) {
// Upcast is always safe
const SimulationModel* base = static_cast<const SimulationModel*>(model);
std::cout << "Static cast (upcast) result: " << base->info() << std::endl;
}
// Function to demonstrate dynamic_cast
void demonstrateDynamicCast(const SimulationModel* model) {
const EulerSolver* eulerSolver = dynamic_cast<const EulerSolver*>(model);
if (eulerSolver) {
std::cout << "Dynamic cast to EulerSolver succeeded\n";
eulerSolver->eulerSpecificMethod();
} else {
std::cout << "Dynamic cast to EulerSolver failed\n";
}
}
// Function to demonstrate const_cast (use with caution!)
void demonstrateConstCast(const SimulationModel* model) {
SimulationModel* non_const_model = const_cast<SimulationModel*>(model);
std::cout << "Const cast result: " << non_const_model->info() << std::endl;
}
// Function to demonstrate reinterpret_cast (use with extreme caution!)
void demonstrateReinterpretCast(const SimulationModel* model) {
uintptr_t address = reinterpret_cast<uintptr_t>(model);
std::cout << "Reinterpret cast result (address): " << address << std::endl;
}
// Function to demonstrate type identification
void demonstrateTypeId(const SimulationModel* model) {
std::cout << "Type of model: " << typeid(*model).name() << std::endl;
}
int main() {
std::vector<std::unique_ptr<SimulationModel>> solvers;
solvers.push_back(std::make_unique<EulerSolver>());
solvers.push_back(std::make_unique<RK4Solver>());
for (const auto& solver : solvers) {
std::cout << "\nSolver: " << solver->info() << std::endl;
std::cout << solver->solve() << std::endl;
demonstrateStaticCast(solver.get());
demonstrateDynamicCast(solver.get());
demonstrateConstCast(solver.get());
demonstrateReinterpretCast(solver.get());
demonstrateTypeId(solver.get());
}
return 0;
}