简体   繁体   中英

How to overwrite a pure virtual function with dynamic binding

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 .

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);

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM