如何将函数中的派生对象作为C ++中的基础对象传递 [英] How to pass derived object in function as base object in C++

查看:81
本文介绍了如何将函数中的派生对象作为C ++中的基础对象传递的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试做这样的事情.

I was trying to do something like this.

class ODESolver
{
public:
    // Fourth-order Runge-Kutta ODE solver.
    static void RungeKutta4(ODE ode, double stepSize)
    {
        // Define some convenience variables to make the
        // code more readable
        int j;
        int numEqns = ode.getNumberOfEquations();
        double s;
        double *q;
        double *dq1 = new double[numEqns];
        double *dq2 = new double[numEqns];
        double *dq3 = new double[numEqns];
        double *dq4 = new double[numEqns];

        // Retrieve the current values of the dependent
        // and independent variables.
        s = ode.getIndependentVar();
        q = ode.getAllIndependentVariables();

        dq1 = ode.getRightHandSide(s, q, q, stepSize, 0.0);
        dq2 = ode.getRightHandSide(s + 0.5*stepSize, q, dq1, stepSize, 0.5);
        dq3 = ode.getRightHandSide(s + 0.5*stepSize, q, dq2, stepSize, 0.5);
        dq4 = ode.getRightHandSide(s + stepSize, q, dq3, stepSize, 1.0);

        // Update the dependent and independent variable values
        // at the new dependent variable location and store the
        // values in the ODE object arrays.
        ode.setIndependentValue(s + stepSize);

        for (j = 0; j < numEqns; j++)
        {
            q[j] = q[j] + (dq1[j] + 2.0*dq2[j] + 2.0*dq3[j] + dq4[j]) / 6.0;
            ode.setDependentValue(q[j], j);
        }
    }
};

class ODE
{
    // Declare fields used by the class
private:
    int numEqns; // number of equations to solve
    double *dependent; // array of dependent variables
    double independent; // independent variable
    // Constructor
public :
    // Constructor
    ODE:: ODE(int numEqns) {
        this->numEqns = numEqns;
        dependent = new double[numEqns];


    virtual double* getRightHandSide(double IndependentVariable, double DependentVariables[],
    double DeltaOfDependents[], double DIndependent, double DependentScale);

};

class SimpleProjectile : public ODE {

public:
    // Gravitational acceleration.
    static double Gravity;

    SimpleProjectile::SimpleProjectile(double x0, double y0, double vx0, double vy0,
        double t);

    // These methods return the location, velocity,
    // and time values.
    double getVx();
    double getVy();
    double getX();
    double getY();
    double getTime();

    // This method updates the velocity and position
    // of the projectile according to the gravity-only model.
    void updateLocationAndVelocity(double dt);

    // Because SimpleProjectile extends the ODE class,
    // it must implement the getRightHandSide method.
    // In this case, the method returns a dummy array.
    double* getRightHandSide(double s, double Q[],
    double deltaQ[], double ds, double qScale)
};


void SimpleProjectile::updateLocationAndVelocity(double dt)
{
    double time = getIndependentVar();
    double vx0 = getDependentVar(0);
    double x0 = getDependentVar(1);
    double vy0 = getDependentVar(2);
    double y0 = getDependentVar(3);

    // Update the xy locations and the y-component
    // of velocity. The x-velocity doesn't change.
    double x = x0 + vx0*dt;
    double vy = vy0 + Gravity*dt;
    double y = y0 + vy0*dt + 0.5*Gravity*dt*dt; // s = S0 + (V0 * t + 1/2 a*t^2)

    //Update Time
    time = time + dt;

    //Load new values into ODE 
    setIndependentValue(time);
    setDependentValue(x, 1);
    setDependentValue(y, 4);
    setDependentValue(vy, 3);
}

class DragProjectile : public SimpleProjectile {

private : 
    double mass, area, density, Cd;

public:
    DragProjectile::DragProjectile(double x0, double y0,
    double vx0, double vy0, double time,
    double mass, double area, double density, double Cd);

    // These methods return the value of the fields
    // declared in this class.
    double getMass();
    double getArea();
    double getDensity();
    double getCd();

    // This method updates the velocity and location
    // of the projectile using a 4th order Runge-Kutta
    // solver to integrate the equations of motion.
    void updateLocationAndVelocity(double dt);

    double* getRightHandSide(double IndependentVariable, double DependentVariables[],
        double DeltaOfDependents[], double DIndependent, double IndependentScale);
};
void DragProjectile::updateLocationAndVelocity(double dt)
{
    ODESolver::RungeKutta4(this, dt); // this is where problem comes in
}

现在我想将 DragProjectile 作为 ODE 对象传递到 ODESolver :: RungeKutta4 中,因为它的派生类 SimpleMotion SimpleMotion 是从 ODE 类派生的. 我尝试过转换,但找不到关键字"this"的解决方法

now i want to pass the DragProjectile in the ODESolver::RungeKutta4 as ODE Object because its derived class of SimpleMotion and SimpleMotion is derived off ODE class. I tried upcasting, but i dont find a work around for keyword : "this"

推荐答案

this是一个指针,但是您的函数需要一个对象.因此,取消引用指针以获取对象:

this is a pointer, but your function expects an object. So dereference the pointer to get the object:

equationSolver::method1(*this, dt);
                        ^

我怀疑该函数可能应该通过引用(甚至是指针)而不是值来引用equation;但这只是基于很少信息的预感.

I suspect that the function should probably take the equation by reference (or maybe even pointer) rather than value; but that's just a hunch based on little information.

这篇关于如何将函数中的派生对象作为C ++中的基础对象传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆