Lord Labakudas said:
Thanks for the useful information. Here is exactly what I am
attempting to do:
I am trying to develop a class of optimization algorithms that
consists of two parts:
1. An optimization engine that is common to all algorithms and acts on
(or takes as input) a generic data type (say, Data).
2. An objective function that is different for different algorithms,
and each act on specific data types (either an int, or a double, or a
vector, etc.,)
My plan to tackle this situation was to create a abstract base class
called Data on which the optimization engine acts on, and hence the
optimization engine is generic. The optimization engine itself is a
abstract base class (called OptimizationEngine) that contains the
following function
virtual double objfunc(const Data *)=0;
The actual optimization algorithms are classes derived from the
OptimizationEngine that overload the objective function class and then
typecast the Data pointer into whatever form they want. The candidates
for data include int, Vector, double, etc., (a mix of intrinsic and
defined classes). All the valid data types that can be used for the
obj func must be derived from Data. So, how to accomplish this without
using templates ?
Any ideas will be greatly appreciated.
Thanks,
Vijay
You might want to look at the Design Patterns book, in particular the
Strategy
pattern. This will make your design a bit more flexible, since you would be
able to vary both the optimization engine and the data class separately. As
an outline,
class NumberCruncher : public ......
{
public:
NumberCruncher( Engine* engine, Data* data );
double doNumberCrunching( )
{
return _engine->objfunc( _data ) ;
}
private:
Engine* _engine;
Data* _data;
};
.....
Engine* beanCounter = new BeanCounterEngine( 42 );
Data* beans = new BeanData();
NumberCruncher lazybeanCounter( beanCounter, beans );
Here Engine is an abstract class and engine would be some derived class from
Engine.
Similarly for Data and data. The advantage of this approach over
inheritance is that
if you have N Engines and M Data subclasses, you would have M*N different
possible subclasses
if you used in heritance, where as you only have 1 class in the above case.
Another advantage
is that Engine could be customized ( say for level of effort or accuracy of
results ) and then
plugged into the NumberCruncher class, thus giving you even more
flexibility.
Engine* beanCounter = new BeanCounterEngine( 42 );
Data* beans = new BeanData();
beanCounter->setAccuracy( 0.00001);
beanCounter->setLevelOfEffort( 1000000 );
NumberCruncher meanbeanCounter( beanCounter, beans );
You might even do all this with templates, this would remove the condition
that the Engine and
Data classes be related through inheritance, you could use any classes
provided they supported
the required interface ( like objfunc() ). If you look at Modern C++
Design by Andrei Alexandrescu
( I think that's how you spell his name), he writes about policy classes
which might work for
you in this situation
hope that helps.
dave