example.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#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;
}
Back to wk14_miscellaneous