C++ 如何在函数中传递派生对象作为C+中的基对象+;
我试着做这样的事情C++ 如何在函数中传递派生对象作为C+中的基对象+;,c++,oop,C++,Oop,我试着做这样的事情 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;
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
}
ODESolver类
{
公众:
//四阶龙格库塔常微分方程求解器。
静态无效RungeKutta4(常微分方程,双步长)
{
//定义一些方便变量以使
//代码更具可读性
int j;
int numEqns=ode.getNumberOfEquations();
双s;
双*q;
double*dq1=新的double[numEqns];
双精度*dq2=新双精度[numEqns];
双精度*dq3=新双精度[numEqns];
双精度*dq4=新双精度[numEqns];
//检索依赖项的当前值
//和自变量。
s=ode.getIndependentVar();
q=ode.getAllIndependentVariables();
dq1=ode.getRightHandSide(s,q,q,步长,0.0);
dq2=ode.getRightHandSide(s+0.5*步长,q,dq1,步长,0.5);
dq3=ode.getRightHandSide(s+0.5*步长,q,dq2,步长,0.5);
dq4=ode.getRightHandSide(s+stepSize,q,dq3,stepSize,1.0);
//更新因变量和自变量值
//在新的因变量位置,并存储
//ODE对象数组中的值。
ode.setIndependentValue(s+步长);
对于(j=0;jnumEqns=numEqns;
从属=新双精度[numEqns];
虚拟双*getRightHandSide(双独立变量,双从属变量[],
双DeltaOfDependents[],双依赖,双依赖;
};
类simpleproject:public-ODE{
公众:
//重力加速度。
静态双重重力;
SimpleProject::SimpleProject(双x0,双y0,双vx0,双vy0,
双t);
//这些方法返回位置、速度、,
//和时间值。
双getVx();
双getVy();
双getX();
双getY();
双getTime();
//此方法将更新速度和位置
//根据仅重力模型计算弹丸的重量。
空隙更新位置和速度(双dt);
//因为SimpleProject扩展了ODE类,
//它必须实现getRightHandSide方法。
//在本例中,该方法返回一个伪数组。
double*getRightHandSide(双s,双Q[],
双deltaQ[],双ds,双qScale)
};
void simpleproject::updateLocationAndVelocity(双dt)
{
double time=getIndependentVar();
双vx0=getDependentVar(0);
双x0=getDependentVar(1);
双vy0=getDependentVar(2);
双y0=getDependentVar(3);
//更新xy位置和y形元件
//速度,x速度不变。
双x=x0+vx0*dt;
双vy=vy0+重力*dt;
双y=y0+vy0*dt+0.5*重力*dt*dt;//s=S0+(V0*t+1/2 a*t^2)
//更新时间
时间=时间+dt;
//将新值加载到ODE中
设置独立值(时间);
setDependentValue(x,1);
setDependentValue(y,4);
setDependentValue(vy,3);
}
类DragProjectle:公共SimpleProjectle{
私人:
双质量,面积,密度,Cd;
公众:
拖曳投影::拖曳投影(双x0,双y0,
双倍vx0,双倍vy0,双倍时间,
双质量、双面积、双密度、双Cd);
//这些方法返回字段的值
//在这个类中声明。
双getMass();
双getArea();
双重密度();
双getCd();
//此方法将更新速度和位置
//用四阶龙格库塔法计算弹丸的速度
//解算器,用于积分运动方程。
空隙更新位置和速度(双dt);
double*getRightHandSide(双独立变量,双从属变量[],
双DeltaOfDependents[],双D相关,双独立量表);
};
无效DragProjectle::更新定位和速度(双dt)
{
ODESolver::RungeKutta4(this,dt);//这就是问题所在
}
现在我想将ODSolver::RungeKutta4中的DragProjectle作为ODE对象传递,因为它的派生类SimpleMoment和SimpleMoment是从ODE类派生的。
我试过向上投射,但我找不到一个关键字:“this”应该是吗
equationSolver::method1(*this, dt);
或者更好的是,使该函数接受指针:
class equationSolver{
public:
static void method1(equation* eq, double dt);
}
那么你最初的电话就可以了
更新:
您可能还需要公共继承:
class simpleMotion : public equation
你知道吗
static void method1(equation eq, double dt);
应为等式的对象,而不是指向eq的指针
所以如果你把这个方法改成
static void method1(equation* eq, double dt);
以下内容应按原样工作
equationSolver::method1(this, dt); // i am getting error here...
因为SimpleMootion是一个等式,所以这是一个指针,但您的函数需要一个对象。因此,取消对指针的引用以获取对象:
equationSolver::method1(*this, dt);
^
我怀疑函数应该通过引用(甚至可能是指针)而不是值来获取
方程;但这只是一个基于少量信息的预感。你能包含你得到的确切错误消息吗?“没有合适的方法将SimpleMootion转换为方程”;先生,我现在得到这个错误。。。“没有合适的方法将简单的情绪转化为方程式“;@MuhammadFaizan:那是因为继承是私有的;将类定义更改为class SimpleMootion:public equation
或struct SimpleMootion:equation
,以使其公开。虽然您发布的代码不应该有问题。我也这么做了,但仍然不走运。@MuhammadFaizan:那么您就有了。”