Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] Tipos mutuamente referenciados - error: 'x' no se declaró en este ámbito.

Estas en el tema de Tipos mutuamente referenciados - error: 'x' no se declaró en este ámbito. en el foro de C/C++ en Foros del Web. He escrito dos tipos (clases) que poseen miembros mutuos por cuestiones del compilador en ambos archivos esta declarado el "include" donde se puede encontrar el ...
  #1 (permalink)  
Antiguo 06/06/2014, 08:26
Tupac01
Invitado
 
Mensajes: n/a
Puntos:
Tipos mutuamente referenciados - error: 'x' no se declaró en este ámbito.

He escrito dos tipos (clases) que poseen miembros mutuos por cuestiones del compilador en ambos archivos esta declarado el "include" donde se puede encontrar el otro tipo que necesita en ambos casos. El compilador no esta pudiendo compilar chocando con un error dependiendo de cual tipo se va a compilar de segundo indica 'error: 'x' no se declaró en este ámbito', estoy usando GCC 4.7.1. Estructuralmente me hace total sentido que ambos tipos se referencien entre si, pero ahora me hace pensar que quizas los diseñadores del compilador no lo piensen así. Me gustaría saber que se debe de hacer en este caso.

Gracias,

Tupac
  #2 (permalink)  
Antiguo 06/06/2014, 08:54
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 16 años, 3 meses
Puntos: 61
Respuesta: Tipos mutuamente referenciados - error: 'x' no se declaró en este ámbito.

No tengas un objeto del otro tipo, ten un puntero a un objeto del otro tipo. Todos los punteros tienen igual tamaño, por lo que el compilador no reclamará si incluyes, antes del uso del puntero una linea como

class LaOtraClase;

sin especificar detalles.
Los detalles solo son necesarios cuando se requiere calcular el tamaño de un objeto, y esta restriccion desaparece al usar punteros.
__________________
Visita mi perfil en LinkedIn
  #3 (permalink)  
Antiguo 06/06/2014, 10:36
Tupac01
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Tipos mutuamente referenciados - error: 'x' no se declaró en este ámbito.

Al parecer no es tan simple:

Código:
#ifndef A
#define A
#include "t2.cpp"

class t1 {
    t2* var;
};
#endif
entoces:

Código:
#ifndef B
#define B
#include "t1.cpp"

class t2 {
    t1* var;
};
#endif
con una llamada

Código:
#include "t1.cpp"

int main() {
    t1 obj;
    return 0;
}
Te tiene que dar un error de recursividad, "error: 't1' no nombra a un tipo". De repente se me ocurre declarar el "#include" en la parte inferior del archivo, pero siento que se pierde la elegancia del código. Que tal ¿que piensan ustedes?
  #4 (permalink)  
Antiguo 06/06/2014, 10:53
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 16 años, 3 meses
Puntos: 61
Respuesta: Tipos mutuamente referenciados - error: 'x' no se declaró en este ámbito.

Elimina los #include que tienes.
En vez de #include "t1.cpp" pon
class t1;
como te indiqué.

La version simplificada es:

t1.h

Código C++:
Ver original
  1. class T2;
  2. class T1 {
  3.    T2* p2;
  4. };

t2.h

Código C++:
Ver original
  1. class T1;
  2. class T2 {
  3.    T1* p1;
  4. };

main
Código C++:
Ver original
  1. #include "t1.h"
  2. #include "t2.h"
  3.  
  4. int main() {
  5.    T1 t1;
  6.    T2 t2;
  7. }
__________________
Visita mi perfil en LinkedIn
  #5 (permalink)  
Antiguo 09/06/2014, 09:06
Tupac01
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Tipos mutuamente referenciados - error: 'x' no se declaró en este ámbito.

CalgaryCorpus,

Me parece haber tomado tu recomendación al pie de la letra. Se ha transformado en otro problema, especificamente cuando el enlazador da el error de que las funciones estan sin definir.
Hice el siguiente cambio en t1.h:

Código:
class t2;
class t1 {
    t2* var;
public:
    void pont2();
   const t2& sacat2();
}
cree a t1.cpp

Código:
#include "t1.h"

void t1::pont2() {
    var = new t2();
}
    
const t2& t1::sacat2() {
    return *var;
}
me devuelve el siguiente error:

Código:
/tmp/ccUDgxze.o: En la función `main':
t1.cpp:(.text+0x11): referencia a `t1::pont2()' sin definir
t1.cpp:(.text+0x11): referencia a `t1::sacat2()' sin definir
collect2: error: ld devolvió el estado de salida 1
Tupac01

Última edición por Tupac01; 09/06/2014 a las 09:16
  #6 (permalink)  
Antiguo 09/06/2014, 13:35
Tupac01
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Tipos mutuamente referenciados - error: 'x' no se declaró en este ámbito.

Pues este problema demostró ser bastante exigente. El problema no esta en la concepto de los tipos mutuamente referenciados. La cuestión esta en la manera que funciona el compilador con el enlazador. La manera que pude resolverlo es haciendo un "makefile" donde compile 3 archivos objeto uno por cada archivo de encabezado o de código para tal caso, y por ultimo compilar ejecutable teniendo los archivos objeto. En concepto utilice el método de separar la compilación en sus unidades mas pequeñas para después resolver el enlazado. Tuve que recurrir hacer la inclusión del archivo de encabezado de t2.cpp, de nuevo en t1.h para que el compilador me reconociera el uso de los objetos en las funciones.

Busque bastante sobre esto no pude encontrar nadie que se había enfrentado a esto por lo menos no documentado, pero espero que ha alguien le sirva.

Saludos
  #7 (permalink)  
Antiguo 09/06/2014, 15:38
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 16 años, 3 meses
Puntos: 61
Respuesta: Tipos mutuamente referenciados - error: 'x' no se declaró en este ámbito.

Siempre que requieras la *definicion* de la clase tienes que #incluir su definicion (tipicamente, en el .h). Los punteros a un tipo no requieren esa definicion, con el "class Clase;" basta.

Al linkear se requiere la implementacion de todo, por supuesto.

La compilación separada ayuda en el largo plazo pues compilar requiere CPU (y tiempo) y si tienes clases que no cambias, no quieres andar compilándolas a cada rato sin motivo.
__________________
Visita mi perfil en LinkedIn

Etiquetas: clases
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 03:25.