Thank you Stewbond, but I think the situation I'm facing is different than you have imagined.
It actually appears that I need to use both solutions!
I have a class hierarchy of function objects:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
class moveEquations// abstract base
{
public:
virtual float s( float t ) = 0;// gives position along an arc as a function of the time
moveEquations();
virtual ~moveEquations();
};
// for speed = constant
class constV : public moveEquations
{
public:
float v;// speed
virtual float s( float t )
{ return v*t; }
constV( float V ): v(V) {}
};
// for acceleration = constant
class constAcc : public moveEquations
{
public:
float v0;// speed at t = 0
float a;// acceleration
virtual float s( float t )
{ return v0*t + a*t*t/2.0f; }
constAcc( float V0, float acc ): v0(V0), a(acc) {}
constAcc( float V0, float Vf, float period ): v0(V0) { a = (Vf-V0)/period; }
};
|
Two classes exist, each having an inherited pointer to a moveEquation as a data member, and a copy ctor (among other things)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
#include "moveEquations.h"
class Lbase// define the shape of the arc being traveled upon
{
moveEquation* pMotion;
virtual float x( float t ) = 0;// pMotion used here
virtual float y( float t ) = 0;// and here
}
class L1 : public Lbase
{
L1( const L1& rL1 );
.....
}
class L2 : public Lbase
{
L2( const L2& rL2 );
.....
}
|
Either a constV or a constAcc object is allocated to pMotion when either an L1 or L2 object is constructed (depending on which ctor is used - not shown).
If an L1 or L2 object has to be copied, then a new instance of a moveEquation must be created for the new L1 or L2 objects pMotion member to point to, as you have correctly pointed out.
It turns out that in class L1 it is fine to copy the moveEquation object "as-is", ie. without also modifying the values of the moveEquations data members.
In this case, a clone() works great!
1 2 3 4 5
|
L1::L1( const L1& rL1 )
{
pMotion = rL1.pMotion->clone();// sweet!!
.....
}
|
However, in class L2 it is necessary to "reset'" the state of the moveEquation being copied:
1 2 3 4 5 6 7 8 9 10 11 12
|
L2::L2( const L2& rL2 )
{
switch( rL2.pMotion->get_id() )// 2nd solution method used
{
case: 1
pMotion = new constV( 7.5 );// reset value of v
break;
case: 2
pMotion = new constAcc( 5.0, 3.2 );// reset values of v and a
break;
.....
}
|
So, incredibly, I am implementing BOTH methods:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
class moveEquations
{
public:
virtual float s( float t ) = 0;
virtual moveEquations* clone() const = 0;// using clone pattern (jsmiths solution )
virtual unsigned get_id() = 0;// Hamstermans solution
moveEquations();
virtual ~moveEquations();
};
// for speed = constant
class constV : public moveEquations
{
public:
float v;// speed
virtual float s( float t )
{ return v*t; }
virtual constV* clone() const
{ return new constV( *this ); }
virtual unsigned get_id() { return 1;}
constV( float V ): v(V) {}
};
// for acceleration = constant
class constAcc : public moveEquations
{
public:
float v0;// speed at t = 0
float a;// acceleration
virtual float s( float t )
{ return v0*t + a*t*t/2.0f; }
virtual constAcc* clone() const
{ return new constAcc( *this ); }
virtual unsigned get_id() { return 2;}
constAcc( float V0, float acc ): v0(V0), a(acc) {}
constAcc( float V0, float Vf, float period ): v0(V0) { a = (Vf-V0)/period; }
};
|
EDIT: Numerous typos. Adding code comments