Stuck in a pattern requirement loop
I have a class that uses the "add-on" pattern to add additional functionality as shown below:
template< class T >
class AddOn_A
{
public:
int SomeFuncA()
{
T* pT = static_cast< T* >( this );
return pT->DoSomething() + 1;
};
};
class CMyClass : public AddOn_A< CMyClass >
{
public:
int DoSomething()
{
return 100;
};
};
int _tmain(int argc, _TCHAR* argv[])
{
CMyClass A;
_ASSERT( A.SomeFuncA() == 101 );
return 0;
}
Now I would like to expand on this so that CMyClass can accept various additions like AddOn_B.
template< class T >
class AddOn_B
{
public:
int SomeFuncB()
{
T* pT = static_cast< T* >( this );
return pT->DoSomething() + 2;
};
};
template< class AddOn >
class CMyClass : public AddOn
{
public:
int DoSomething()
{
return 100;
};
};
int _tmain(int argc, _TCHAR* argv[])
{
// error C3203: 'AddOn_A' : unspecialized class template can't be used as a template argument for template parameter 'AddOn', expected a real type
// error C2955: 'AddOn_A' : use of class template requires template argument list
CMyClass< AddOn_A > A;
_ASSERT( A.SomeFuncA() == 101 );
// same errors here
CMyClass< AddOn_B > B;
_ASSERT( B.SomeFuncB() == 102 );
return 0;
}
Unfortunately every Add_On item requires CMyClass as a template parameter, which requires Add_On, etc. I'm in a demand loop.
Is there some kind of template magic I can use to get the functionality I'm looking for? Is there a better way to do this?
Thanks, PaulH
source to share
Apparently you are trying to use the famous curious repeating pattern pattern .
I'm not sure what you exactly want to do, but you can get away with another solution:
What if you used two classes:
class Base {};
class MyClass: public AddOn<Base> {};
You can also take a political approach:
class PolicyA_A {};
class PolicyA_B {};
class PolicyB_A {};
class PolicyB_B {};
template <class PolicyA, class PolicyB>
class MyClass: private PolicyA, private PolicyB {};
typdef MyClass<PolicyA_A, PolicyB_A> MyClassAA;
The idea is to delegate some of the work to politicians to add flexibility.
Finally, you can use Decorator :
class Base {};
template <class T>
class AddOn_A: public T {};
class MyClass: public AddOn_A< AddOn_B< Base > > {};
This allows you to get rid of virtual inheritance by suppressing Multi Inheritance and making the hierarchy linear.
source to share