Duda programacion c++

Buenas, no se muy bien si esto va aquí o no, pero es q si no, no se dónde postear.
Al grano, estoy programando en C++ y tengo un problema de referencias circulares (o cruzadas) a la hora de compilar, por si no sabéis lo que es os lo explico: Tengo dos clases, A y B, cada una tiene su .h y su .cpp. La clase A tiene un atributo del tipo B y la clase B tiene un atributo del tipo A, de manera que en cada uno de los .h tengo que hacer un #include del otro fichero. Utilizo las directivas #ifndef y #define para evitar que entren en un bucle a la hora de hacer includes. El caso es que me da un error porque en uno de los archivos no se hace el include y no reconoce el tipo de dato de la otra clase. No se si me habré explicado bien. Por si acaso:

---a.h---
#ifndef __A_H__
#define __A_H__

#include "b.h"

class B;

class A{
public: ...
private:
B atributo;
};

#endif

---b.h---
#ifndef __B_H__
#define __B_H__

#include "a.h"

class A;

class B{
public: ...
private:
A atributo;
};

#endif

A ver si alguien me puede decir que hacer, porque he mirado por todos lados pero no me funciona de ninguna manera. Me tiene frito.

Graciaaas de antemano!!
No incluyas b.h en a.h si ya has declarado class B; allí.

- ferdy
Felicidades Ferdy!!!
Has llegado a los 4K mensajes!!!

Saludos
He hecho lo que me has dicho Ferdy, pero es que entonces me da muchos mas errores, de la manera en que está una de las clases compila bien, pero la otra es la que me falla. Por si os puedea servir os pongo el error:

/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_pair.h: In instantiation of ‘std::pair<Cruce, Cruce>’:
tramo.h:33: instantiated from here

/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_pair.h:73: error: ‘std::pair<_T1, _T2>::first’ has incomplete type
tramo.h:10: error: forward declaration of ‘struct Cruce’

/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_pair.h:74: error: ‘std::pair<_T1, _T2>::second’ has incomplete type
tramo.h:10: error: forward declaration of ‘struct Cruce’

En realidad la clase A es Cruce y la B es Tramo. Y tramo tiene como atributos un pair de cruces.
A la hora de compilar se que el error tiene que ver con la declaracion anticipada, pero es que si la quito no me reconoce la clase Cruce , aunque siga estando el include, es decir, me salen los tipicos "‘Cruce’ was not declared in this scope".

Alguna sugerencia más?
(Gracias de todas formas Ferdy!)
Si, pega el código y te podré ayudar.

- ferdy
Ok. Este es tramo.h:

#ifndef TRAMO_H
#define TRAMO_H

#include <utility>
#include <string>
#include "cruce.h"

using namespace std;

class Cruce;

class Tramo{
public:
Tramo();
Tramo(string nombre,float longitud,const pair<Cruce,Cruce> &extremos);
~Tramo();
Tramo(const Tramo &t);

Tramo& operator=(const Tramo &t);
bool operator==(const Tramo &t) const;
string get_nombre()const;
float get_longitud()const;
pair<Cruce,Cruce> get_extremos()const;

void set_nombre(string nombre);
void set_longitud(float longitud);
void set_extremos(const pair<Cruce,Cruce> &extremos);


private:
string nombre;
float longitud;
pair<Cruce,Cruce> extremos;

};


#endif

Y este cruce.h:

#ifndef CRUCE_H
#define CRUCE_H

#include <utility>
#include <string>
#include <list>
#include "tramo.h"


using namespace std;

class Tramo;

class Cruce{
public:
Cruce();
Cruce(string nombre,unsigned int id,const pair<float,float> &coord, const list<Tramo> &lista);
~Cruce();
Cruce(const Cruce &c);
Cruce& operator=(const Cruce &c);
bool operator==(const Cruce &c) const;

unsigned int get_id()const;
string get_nombre()const;
pair<float,float> get_coordenadas()const;
list<Tramo> get_tramos()const;

void set_nombre(string nom);
void set_id(unsigned int id);
void set_coordenadas(const pair<float,float> &coord);
void set_tramos(const list<Tramo> &l);

private:
string nombre;
unsigned int id;
pair<float,float> coordenadas;
list<Tramo> lista;

};

#endif

A ver si te sirve. Y gracias de nuevo!!
Oh, je.

Creo que te toca usar un puntero. Puedes tener un puntero a un tipo parcialmente definido...

Eso o usar PIMP (PrivateImplementationPattern).

- ferdy

PD: Igual hay algún otro modo de solucionarlo... pero ahora no caigo.
Ok, muuchas gracias Ferdy!!
7 respuestas