I am attempting to use static polymorphism to create a decorator pattern.
As to why I do not use dynamic polymorphism, please see this QA. Basically, I could not dynamic_cast
to each decorator so as to access some specific functionality present only in the decorators (and not in the base class A).
With static polymorphism this problem has been overcome, but now I cannot register all the et()
methods from the decorators back to the base class A (as callbacks or otherwise), thus when A::et()
gets called, only A::et()
and Z::et()
get executed. I want all of A,X,Y,Z ::et()
to be executed (the order for X,Y,Z does not matter).
How can I do that using the following structure?
I can see in wikipedia that CRTP should allow you to access member of a derived class using static_cast
, but how do you approach the problem when there are multiple derived template classes?
If this is not possible with static polymorphism but it is possible with dynamic polymorphism could you reply to the other question?
struct I {
virtual void et() = 0;
};
class A : public I {
public:
A() {
cout << "A::ctor " ;
decList.clear();
}
void regDecorator(I * decorator)
{
if (decorator) {
cout << "reg= " << decorator << " ";
decList.push_back(decorator);
}
else
cout << "dec is null!" <<endl;
}
virtual void et()
{
cout << "A::et ";
cout << "declist size= " << decList.size() << endl;
list<I*>::iterator it;
for( it=decList.begin(); it != decList.end(); it++ )
static_cast<I *>(*it)->et();
}
std::list<I*> decList; //FIXME
};
template<typename Base>
class X: public Base {
public:
X(){
cout << "X::ctor ";
Base::regDecorator(this);
}
virtual void et(){
cout << "X::et" <<endl;
}
};
template<typename Base>
class Y: public Base {//public D {
public:
Y(){
cout << "Y::ctor ";
Base::regDecorator(this);
}
void et(){
cout << "Y::et" <<endl;
}
};
template<typename Base>
class Z: public Base {//public D {
public:
Z() {
cout << "Z::ctor ";
Base::regDecorator(this);
}
void et(){
cout << "Z::et" <<endl;
}
};
int main(void) {
Z<Y<X<A> > > mlka;
cout << endl;
mlka.et();
return 0;
}
This structure is to be used as a reference for data acquisition from a set of sensors. class A is the base class and contains common functionality of all the sensors. This includes:
- data container (f.e. `boost::circular_buffer`) to hold an amount of timestamped sample data acquired from the sensor.
- a Timer used to measure some timed quantities related to the sensors.
- other common data and calculation methods (fe. `calculateMean()`, `calculateStdDeviation()`)
In fact the A::timer
will call A::et()
on completion in order to perform some statistical calculations on the sampled data.
Similarly, X,Y,Z are types of sensor objects each with responsibility to extract different type of information from the sampled data. and X,Y,Z::et()
perform a different type of statistical calculation on the data. The aim is perform this calculation as soon as the A::Timer
waiting time elapses. This is why I want to have access to all of X,Y,Z::et() from A::et(). Is it possible without affecting the static polymorphism shown in the example?
Thank you