Solution: linking classes using their derived pointer types (type-safe!)

I

ivan.leben

I am writing this in a new thread to alert that I found a solution to
the problem mentioned here:
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/7970afaa089fd5b8
and to avoid this topic getting lost before people interested in the
problem notice it.

The important tricks to the solution are two:
1) make the custom classes take a TEMPLATE argument which defines their
BASE class
2) EMBED the custom classes in a "Traits" class which is passed as
template argument to the Mesh class instead of passing them directly

(1) makes your class being a derived class that takes a generic base
class which doesn't have to be explicitly given. (2) allows you to pass
the custom classes as template arguments to the Mesh class without
immediately specifying their own template argument (i.e. their base
class).

The final custom classes are fully defined and instantiated only inside
the Mesh class which in turn contains nested classes that become base
classes of custom classes. Just before the definition of these nested
(i.e. base) classes, there is a forward declaration of final classes
which gives template arguments to custom classes and again before it a
forward declaration of base classes.

Here is a partial implementation of the solution, showing the type-safe
inter-linking of custom Vertex and Edge classes

//Mesh.h
////////////////////////////////////////////////////////

template <class MeshTraits>
class Mesh {
public:

//forward declaration of base classes
class BaseVertex;
class BaseEdge;

//forward declaration of final classes (using base classes as
template arguments)
typedef typename MeshTraits :: template Vertex<BaseVertex> Vertex;
typedef typename MeshTraits :: template Edge<BaseEdge> Edge;

//nested base classes follow

class BaseVertex {
public:
Edge *edge;
};

class BaseEdge {
public:
Vertex *vert;
};
};

//MeshTest.cpp
////////////////////////////////////////////////////////

#include <stdio.h>

class MyMeshTraits {
public:

//Vertex class taking a generic base class
template<class Base> class Vertex : public Base {
public:

//custom member
int a;

//function using BaseVertex edge pointer to
//get to edge's custom member

void printEdgeB() {
printf("edge's b = %d\n", Base::edge->b);
}
};

//Edge class taking a generic base class
template<class Base> class Edge : public Base {
public:

//custom member
int b;

//function using BaseEdge vert pointer to
//get to vert's custom member

void printVertA() {
printf("vert's a = %d\n", Base::vert->a);
}
};
};

int main(int argc, char **argv) {

//a little code to test things
Mesh<MyMeshTraits>::Vertex vert;
Mesh<MyMeshTraits>::Edge edge;
vert.a = 20;
edge.b = 40;
vert.edge = &edge;
edge.vert = &vert;
vert.printEdgeB();
edge.printVertA();
};
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top