Reputation: 1
I'm attempting to solve exercise 7.3 in the Pitt-Francis text https://link.springer.com/book/10.1007/978-3-319-73132-2 regarding an abstract ODE class.
The abstract class is given as
class AbstractODESolver
{
private:
...
public:
....
virtual double RightHandSide(double y, double t) = 0;
virtual double SolveEquation() = 0;
};
The derived class is given as
class ForwardEuler: public AbstractODESolver
{
public:
double RightHandSide(double y, double t);
double SolveEquation();
};
How would one cast RightHandSide in ForwardEuler so that it may be defined at runtime?
In particular a main file could take the form
double RHS(double y, double t);
int main(int argc, char* argv[])
{
AbstractODESolver* p_ODEs = new ForwardEuler;
return 0;
}
double RHS(double y, double t)
{
return 1+t;
}
and I would like to write something like
p_ODEs->RightHandSide = &RHS;`
to point to the function RHS
.
Upvotes: 0
Views: 80
Reputation: 1
Here's my solution that doesn't require std::function
, which I think is the required solution given the techniques taught in the chapter.
(As per @Paul Sanders)
class ForwardEuler: public AbstractODESolver
{
public:
ForwardEuler(double (*pRhs)(double, double));
double RightHandSide(double y, double t);
double SolveEquation();
private:
double (*mRhs)(double y, double t);
};
ForwardEuler::ForwardEuler(double (*pRhs)(double, double))
{
mRhs = pRhs;
}
double ForwardEuler::RightHandSide(double y,double t)
{
return (*mRhs)(y,t);
}
main function
double RHS(double y, double t);
int main(int argc, char* argv[])
{
AbstractODESolver* p_ODEs = new ForwardEuler(RHS);
std::cout<<(*p_ODEs).RightHandSide(1.0,1.0)<<std::endl;
return 0;
}
double RHS(double y, double t)
{
return 1+t;
}
Upvotes: 0
Reputation: 7324
Give the ForwardEuler
class a data member to store the function, and pass it in the constructor. The RightHandSide
function will just call the function passed in.
class ForwardEuler: public AbstractODESolver
{
public:
ForwardEuler(std::function<double(double, double)> rhs): rhs(rhs) {}
double RightHandSide(double y, double t) { return rhs(y, t); }
double SolveEquation();
private:
std::function<double(double, double)> rhs;
};
...
double RHS(double y, double t);
AbstractODESolver* p_ODEs = new ForwardEuler(RHS);
Upvotes: 2