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
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <iostream>
#include <vector>
#include <memory>

// Abstract base class for differential equation solvers
class DifferentialEquationSolver {
public:
    virtual ~DifferentialEquationSolver() = default;
    virtual void solve() = 0; // Pure virtual function
    virtual void initialize() { std::cout << "Initializing solver\n"; }
};

// Derived class for Euler method
class EulerSolver : public DifferentialEquationSolver {
public:
    void solve() override {
        std::cout << "Solving using Euler method\n";
    }
};

// Derived class for Runge-Kutta method
class RungeKuttaSolver : public DifferentialEquationSolver {
public:
    void solve() override {
        std::cout << "Solving using Runge-Kutta method\n";
    }
};

// Abstract base class for boundary conditions
class BoundaryCondition {
public:
    virtual ~BoundaryCondition() = default;
    virtual void apply() = 0; // Pure virtual function
};

// Derived class for Dirichlet boundary condition
class DirichletBoundaryCondition : public BoundaryCondition {
public:
    void apply() override {
        std::cout << "Applying Dirichlet boundary condition\n";
    }
};

// Derived class for Neumann boundary condition
class NeumannBoundaryCondition : public BoundaryCondition {
public:
    void apply() override {
        std::cout << "Applying Neumann boundary condition\n";
    }
};

// Base Solver class with adaptive time-stepping capability
class Solver {
public:
    virtual ~Solver() = default;
    virtual void solve() = 0;
};

// Derived AdaptiveSolver class
class AdaptiveSolver : public Solver {
public:
    void solve() override {
        std::cout << "Solving with adaptive time-stepping\n";
    }

    void adjustTimeStep() {
        std::cout << "Adjusting time step\n";
    }
};

// Function to demonstrate polymorphism
void solveProblem(DifferentialEquationSolver& solver) {
    solver.initialize();
    solver.solve();
}


int main() {
    // Demonstrate virtual functions and polymorphism
    std::cout << "Demonstrating virtual functions and polymorphism:\n";
    EulerSolver eulerSolver;
    RungeKuttaSolver rkSolver;

    solveProblem(eulerSolver);
    solveProblem(rkSolver);

    // Demonstrate abstract class usage
    std::cout << "\nDemonstrating abstract class usage:\n";
    std::vector<std::unique_ptr<BoundaryCondition>> boundaryConditions;
    boundaryConditions.push_back(std::make_unique<DirichletBoundaryCondition>());
    boundaryConditions.push_back(std::make_unique<NeumannBoundaryCondition>());

    for (const auto& bc : boundaryConditions) {
        bc->apply();
    }

    // Demonstrate dynamic_cast
    std::cout << "\nDemonstrating dynamic_cast:\n";
    std::vector<std::unique_ptr<Solver>> solvers;
    solvers.push_back(std::make_unique<AdaptiveSolver>());
    // Remove the following line since Solver is abstract:
    // solvers.push_back(std::make_unique<Solver>());

    for (const auto& solver : solvers) {
        solver->solve();

        // Try to cast to AdaptiveSolver
        if (auto adaptiveSolver = dynamic_cast<AdaptiveSolver*>(solver.get())) {
            std::cout << "This is an AdaptiveSolver. ";
            adaptiveSolver->adjustTimeStep();
        } else {
            std::cout << "This is not an AdaptiveSolver.\n";
        }
    }

    return 0;
}
Back to wk04_advanced_OOP