Michael DOUBEZ
9/25/2008 7:59:00 AM
Rune Allnor a écrit :
> I have these classes, implemented as templates in header files.
> Right now I have one file per class, where both the declarations
> and implementations of one class are located in each file.
>
> I would like to apply the visitor pattern to some of these classes.
> One of the technicalities behind the visitor pattern is that one
> needs forward declarations of classes, since there are two
> class hierarchies which refer to each other.
>
> In C++ one can refer to a yet undeclared class in one class'
> *declaration*, but one can't refer to undeclared classes in the
> *implementation*. Since the declaration and implementation
> of my classes reside in the same file, my nice system breaks
> down.
>
> Or I need to set up a very entangled network of declarations
> and implementations, which at the end *might* compile *if*
> all the dependencies are carefully orchestrated. Which in turn
> means that all classes need to know about all the other classes,
> which ultimately destroys the nice modular class hierarchy I
> have right now.
You mean by separating the declaration and implementation, the
implementation (.tcc file) being conditionally included in the header
file ? It might work.
When using the visitor pattern, you cannot however keep this level of
modularity.
> One tempting conclusion from all this is that templates don't
> go well with forward declarations *and* a modular design.
> This seems a bit too 'over the top' to be accepted just like
> that, so am I overlooking something?
Perhaps using a system of delegation. This is burdensome but it would
preserve the modularity somewhat
Example:
*visitor.h:
struct delegate_template1;
struct delegate_template2;
struct delegate_template3;
struct visitor
{
virtual void visit(const delegate_template1&)=0;
virtual void visit(const delegate_template2&)=0;
virtual void visit(const delegate_template3&)=0;
};
*template1.h:
#include "visitor.h"
template<typename T>
struct template1
{
void accept(visitor&v);
};
struct delegate_template1
{
template1<int>* value;
};
template<typename T>
void template1::accept(visitor&v)
{
}
template<>
void template1<int>::accept(visitor&v)
{
delegate_template1 a={this};
v.visit(a);
}
* dans le fichier du visitor:
#include "visitor.h"
#include "template1.h"
//here dont need template2.h or template3.h
struct my_visitor: visitor
{
virtual void visit(const delegate_template1&a)
{
template1<int>* value=a.value;
//...
};
virtual void visit(const delegate_template2&){};
virtual void visit(const delegate_template3&){};
};
--
Michael