Re: on a design question using C++
On Feb 7, 9:42 am, "nvinh...@gmail.com" <nvinh...@gmail.com> wrote:
Hi all,
Thanks to all your support, I managed to write that code. Here it is:
[...]
typedef SofteningLaw<LinearSoftening> LinearSoftLaw;
typedef SofteningLaw<ExponentialSoftening> ExponeSoftLaw;
LinearSoftening linearSoft(10., 50.);
ExponentialSoftening exponeSoft(10., 0.99, 100.);
LinearSoftLaw linear(linearSoft);
ExponeSoftLaw expone(exponeSoft);
// run time
Application app;
app.setSofteningLaw( linear );
This is probably not what you want. Application::setSofteningLaw
expects a policy as an argument, not a law. By coincident passing a
law works here because both policies and the law interface use the
same function names and signatures. But the result here is double
indirection.
To avoid this problem you can either use different function names for
the interface and implementation or hide the runtime polymorphism
within the Application class, or preferably both:
class Application
{
public:
double computeDamage (double k)
{return softening_->f (k);}
double computeDeriOfDamage (double k)
{return softening_->df (k);}
template <class SofteningPolicy>
void setSofteningLaw (const SofteningPolicy& p)
{softening_.reset (new Softening <SofteningPolicy> (p));}
private:
class ISoftening
{
public:
virtual double f (double x) = 0;
virtual double df (double x) = 0;
};
template <class SofteningPolicy>
class Softening :
public ISoftening,
private SofteningPolicy
{
public:
Softening (const SofteningPolicy& p)
: SofteningPolicy (p) {}
virtual double f (double x)
{return SofteningPolicy::evalFunc (x);}
virtual double df (double x)
{return SofteningPolicy::evalDeri (x);}
};
shared_ptr <ISoftening> softening_;
};
Regards,
Vidar Hasfjord