Re: on a design question using C++
Hi all,
Thanks to all your support, I managed to write that code. Here it is:
#include <iostream>
#include <math.h>
#include <boost/shared_ptr.hpp>
using namespace std;
using boost::shared_ptr;
class LinearSoftening
{
public:
LinearSoftening
( double ki, double kc )
: ki_(ki), kc_(kc) {}
double evalFunc ( double x ) { return ki_ + kc_ * x;}
double evalDeri ( double x ) { return kc_;}
private:
double ki_;
double kc_;
};
class ExponentialSoftening
{
public:
ExponentialSoftening
( double ki, double alpha, double beta )
: ki_(ki), alpha_(alpha), beta_(beta){}
double evalFunc ( double x )
{
return ki_ + exp( 1. - alpha_ + beta_ * x );
}
double evalDeri ( double x ) { return alpha_ + beta_;}
private:
double ki_;
double alpha_;
double beta_;
};
class SofteningLawInterface
{
public:
virtual double evalFunc ( double x ) = 0;
virtual double evalDeri ( double x ) = 0;
};
template < class SofteningLawPolicy>
class SofteningLaw : public SofteningLawInterface
{
public:
SofteningLaw
( const SofteningLawPolicy& policy ) : policy_(policy)
{};
double evalFunc ( double x ){ return policy_.evalFunc(x);}
double evalDeri ( double x ){ return policy_.evalDeri(x);}
private:
SofteningLawPolicy policy_;
};
class Application
{
public:
double computeDamage ( double kappa )
{
return softLaw_->evalFunc ( kappa );
}
double computeDeriOfDamage ( double kappa )
{
return softLaw_->evalDeri ( kappa );
}
template <class SoftLawPolicy>
void setSofteningLaw ( const SoftLawPolicy& policy )
{
softLaw_.reset ( new SofteningLaw<SoftLawPolicy>(policy) );
}
private:
shared_ptr<SofteningLawInterface> softLaw_;
};
int main ()
{
// compile time
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 );
// compare performance
const int n = 1000000000;
for ( int i = 0; i < n; i++ )
{
//double fval1 = linear.evalFunc(0.1);
//double fder1 = linear.evalDeri(0.1);
//cout << " fval1: " << fval1 << ", fderi1: " << fder1 << "\n";
double fval2 = app.computeDamage (0.1);
double fder2 = app.computeDeriOfDamage (0.1);
//cout << " fval2: " << fval2 << ", fderi2: " << fder2 << "\n";
}
return 0;
}
I did a performance comparison between object defined at compile time
and at run time,
the result is that the latter is slower than the former:
real 0m43.238s
user 0m43.127s
sys 0m0.088s
real 1m28.149s
user 1m27.965s
sys 0m0.152s
Since I am calling this code in a tight loop, I think that I have to
fall back to the
first approach. But I then lose the beauty and clarity of template
code.
Thanks a lot again.
Phu