[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Templates: Code organization and forward declarations

Rune Allnor

9/24/2008 8:33:00 PM

Hi all.

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.

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?

Rune
1 Answer

Michael DOUBEZ

9/25/2008 7:59:00 AM

0

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