2014-10-07 57 views
0

我試圖做這樣的事情。如何在函數中傳遞派生的對象作爲C++中的基礎對象

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 
} 

現在我想通過DragProjectileODESolver :: RungeKutta4ODE對象,因爲它的派生類的SimpleMotionSimpleMotion推導關閉ODE類。 我試圖向上轉型,但我不尋找周圍工作關鍵字:「這個」

+0

你可以包括你得到的確切的錯誤消息嗎? – Krease 2014-10-07 06:28:11

+0

「沒有合適的方法將simpleMotion轉換爲方程」; – 2014-10-07 06:54:55

回答

0

它不應該是

equationSolver::method1(*this, dt); 

或者更好的是,使該函數接受一個指針:

class equationSolver{ 
public: 
    static void method1(equation* eq, double dt); 
} 

然後你原來的電話應該工作。

更新:

而且你可能想公有繼承:

class simpleMotion : public equation 
+0

先生,我現在得到這個錯誤... 「沒有合適的方式將simpleMotion轉換爲方程」; – 2014-10-07 06:39:40

+0

對,你應該把你的繼承改爲「公共」。 – Ashalynd 2014-10-07 06:42:28

+0

我也公開了,仍然沒有運氣! – 2014-10-07 06:49:44

0

你要明白,這個

static void method1(equation eq, double dt); 

期待式的,而不是指針的目的是EQ

所以如果您只是將此方法更改爲

static void method1(equation* eq, double dt); 

以下應該按原樣工作。

equationSolver::method1(this, dt); // i am getting error here... 

因爲simpleMotion IS_A方程

+0

我試過了,它說: 「類型」SimpleMotion *「的參數與」equation *「類型的參數不兼容 我正在使用Visual Studio作爲IDE – 2014-10-07 06:41:23

1

this是一個指針,但你的函數需要一個對象。所以,解引用指針獲取對象:

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

我懷疑是功能也許應該參照採取equation(或者甚至指針),而不是價值;但這只是基於少量信息的預感。

+0

先生我現在收到此錯誤... 」there沒有合適的方法將simpleMotion轉換爲公式; – 2014-10-07 06:39:15

+1

@MuhammadFaizan:這是因爲繼承是私有的;將類定義更改爲'class simpleMotion:public equation'或'struct simpleMotion:equation'來公開它。雖然這不應該是你發佈的代碼的問題。 – 2014-10-07 06:42:20

+0

我也這樣做了,還是沒有運氣.. – 2014-10-07 06:48:32

相關問題