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

Problema con includes y clases una dentro de la otra

Estas en el tema de Problema con includes y clases una dentro de la otra en el foro de C/C++ en Foros del Web. Hola. Estoy empezando con código c++ viniendo de Java y quizas tenga algun concepto cambiado. Mi problema ahora es el siguiente: clase1{ Clase2 clase2; } ...
  #1 (permalink)  
Antiguo 16/03/2016, 17:55
 
Fecha de Ingreso: marzo-2016
Mensajes: 8
Antigüedad: 3 años, 5 meses
Puntos: 0
Problema con includes y clases una dentro de la otra

Hola.

Estoy empezando con código c++ viniendo de Java y quizas tenga algun concepto cambiado.

Mi problema ahora es el siguiente:


clase1{
Clase2 clase2;
}


clase2{
Clase1 clase1;
}

Todo eso tiene su constructor donde se pasan la referencia y demas....

Si pongo include Clase2 en Clase1, en Clase2 me dice que no existe Clase1 a pesar de tener Include Clase1, y si no lo pongo me dice que no existe Clase2.

En java se que se puede. Aqui... pues ni idea.


Gracias de antemano.
  #2 (permalink)  
Antiguo 16/03/2016, 19:24
Avatar de Instru  
Fecha de Ingreso: noviembre-2002
Ubicación: Mexico
Mensajes: 2.751
Antigüedad: 16 años, 9 meses
Puntos: 52
Respuesta: Problema con includes y clases una dentro de la otra

No es muy clara tu pregunta.

Si a include te refieres a #include, entonces tienes el concepto erroneo.

#include es muy diferente a import. Literalmente #include copia el archivo que incluyes al archivo actual.

Ahora, hablando de clases. En C++ el concepto de declaración/definición es mas marcado que en java.

En el caso de tu código,

Código PHP:
clase1{
Clase2 clase2;
}


clase2{
Clase1 clase1;

Para que funcione correctamente, tienes que declarar ambas clases:

Código PHP:
class clase1;
class 
clase2;

clase1{
Clase2 clase2;
}


clase2{
Clase1 clase1;

De esta manera el compilador sabrá que existe una clase1 y una clase2, pero que su definición está en otra parte.

Saludos
  #3 (permalink)  
Antiguo 17/03/2016, 00:06
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 4 años, 10 meses
Puntos: 204
Respuesta: Problema con includes y clases una dentro de la otra

A lo comentado por Instru, decir que esto solo funcionaría si se usan punteros en al menos una de las clases.

Me explico:
Código C++:
Ver original
  1. class clase1;
  2. class clase2;
  3.  
  4. clase1{
  5. // error. El compilador no conoce el tamaño de Clase2
  6. // por lo que no pude usarse por valor en este punto
  7. Clase2 clase2;
  8. // sin embargo esto si sería válido
  9. Clase2 *clase;
  10. }
  11.  
  12.  
  13. clase2{
  14. Clase1 clase1; // correcto. El compilador conoce el tamaño de Clase1
  15. }

Un saludo
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #4 (permalink)  
Antiguo 17/03/2016, 06:06
 
Fecha de Ingreso: marzo-2016
Mensajes: 8
Antigüedad: 3 años, 5 meses
Puntos: 0
Respuesta: Problema con includes y clases una dentro de la otra

[URL="https://googledrive.com/host/0B5TX1idvrJQxbWpmY2h4M2U4bHM"]https://googledrive.com/host/0B5TX1idvrJQxbWpmY2h4M2U4bHM[/URL]


https://googledrive.com/host/0B5TX1idvrJQxbWpmY2h4M2U4bHM

En ese link hay una imagen, ambos errores señalados señalan a Clase2 does not a type name.


no doy con la formula... de todas formas, disculparme... estoy algo enbotado ya con C++

Última edición por tonyasura; 17/03/2016 a las 06:10 Razón: no consigo poner imagen
  #5 (permalink)  
Antiguo 17/03/2016, 06:34
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 4 años, 10 meses
Puntos: 204
Respuesta: Problema con includes y clases una dentro de la otra

En primer lugar me gustaría hacerte una recomendación. Incluye el código en tu respuesta en vez de usar enlaces a imágenes. Para que el código aparezca conveniente coloreado es necesario elegir el lenguaje que proceda en el desplegable "Highlight". Esto facilita la lectura de los mensajes y permite copiar el código para, por ejemplo, reutilizarlo o comentarte los problemas que tienes.

Cuando tu pones un include en C/C++ estás, literalmente, añadiendo el contenido de dicho fichero. El compilador al encontrar un include buscará el fichero señalado y sustituirá la instrucción del include por el contenido del fichero.

Código C++:
Ver original
  1. #ifndef ALGO
  2. #define ALGO
  3. //...
  4. #endif

El diseño del ejemplo de arriba se usa como salvaguarda para evitar que los includes anidados provoquen duplicidades (si un archivo recibe de dos vías diferentes la declaración de una función la compilación fallará).

El código anterior también puede usarse con otros fines, pero en tu caso el fín es el que te comento. Si las dos clases van a estar en el mismo fichero (y este es una cabecera) únicamente necesitas una guarda. Simplemente haz que la guarda abarque toda la cabecera:

Código C:
Ver original
  1. #ifndef __GUARDA__
  2. #define __GUARDA__
  3.  
  4. class Clase1
  5. {
  6.   // ...
  7. };
  8.  
  9. class Clase2
  10. {
  11.   // ...
  12. };
  13. #endif

Si resulta que me estoy equivocando y que, efectivamente, tienes cada clase en un fichero independiente entonces sí que necesitas dos guardas distintas (una para cada fichero).

Más cosas.

Código C++:
Ver original
  1. class Clase1
  2. {
  3.   public:
  4.     Clase2 c2; // <<--- 1
  5.     Clase2* c2; // <<--- 2,3
  6. };
  1. No puedes usar aquí Clase2 por valor porque el compilador aun no sabe qué es Clase2.
  2. Tampoco puedes usar un puntero a Clase2 porque el compilador no sabe si Clase2 es una estructura, un puntero a función, un puntero a un tipo nativo...
  3. No se puede repetir el nombre de las variables si éstas tienen el mismo ámbito.
Lo siguiente sería más correcto en tu caso (que es similar a lo que te propuso Instru):
Código C++:
Ver original
  1. // Indicas que en el programa va a haber un objeto con nombre Clase2.
  2. // A partir de este momento el compilador sabe que existe este objeto aunque
  3. // aun no tiene ni idea ni de su tamaño ni de cómo se usa... pero sabe que existe
  4. // Esto implica que no podrás usar Clase2 por valor, sino como puntero y
  5. // también implica que no podrás acceder a sus miembros hasta que no pongas
  6. // su declaración completa.
  7. class Clase2;
  8.  
  9. class Clase1
  10. {
  11. public:
  12.   // Tenemos que usar un puntero debido a lo que he se ha explicado unas lineas antes
  13.   Clase2* c2;
  14.  
  15. };
  16.  
  17.  
  18. class Clase2
  19. {
  20. public:
  21.   // Aquí si podemos usar Clase1 por valor porque ya hemos declarado Clase1
  22.   // y, por ello, el compilador ya tiene toda la información necesaria para usarla.
  23.   // Por supuesto también podríamos usar la versión puntero si nos interesa más.
  24.   Clase1 c1;
  25. };

Y con la maravillosamente escueta imagen que has publicado poco más te puedo decir, espero que estas indicaciones te sirvan de algo.

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #6 (permalink)  
Antiguo 17/03/2016, 06:53
 
Fecha de Ingreso: marzo-2016
Mensajes: 8
Antigüedad: 3 años, 5 meses
Puntos: 0
Respuesta: Problema con includes y clases una dentro de la otra

Código C++:
Ver original
  1. #ifndef CLASE1_H
  2. #define CLASE1_H
  3.  
  4. class Clase2;
  5.  
  6. class   Clase1 {
  7. public:
  8. Clase1(){};
  9.  
  10. void setClase(Clase2 * c ){c2 = c;}
  11.  
  12. void unaFuncion(){
  13. //idea 1
  14.     Clase2 c=*c2;//  ERROR
  15.      c.unaFuncion();
  16. //idea 2
  17. c2.unaFuncion(); //Description  Resource    Path    Location    Type    request for member 'unaFuncion' in '((Clase1*)this)->Clase1::c2', which is of pointer type 'Clase2*' (maybe you meant to use '->' ?)    Clase1.h    /test_incluse   line 14 C/C++ Problem
  18. };
  19.  
  20. Clase2 * c2;
  21.     };
  22.  
  23. #endif
  24.  
  25.  
  26. #ifndef CLASE2_H
  27. #define CLASE2_H
  28.  
  29. class   Clase2 {
  30. public:
  31. Clase2(){};
  32.  
  33. void setClase(Clase1 * c ){c1 = c;}
  34.  
  35. void unaFuncion(){
  36.     Clase1 c=*c1;
  37.     c.unaFuncion();
  38. };
  39.  
  40. Clase1 * c1;
  41.  
  42.     };
  43.  
  44. #endif

bueno... he avanzado un poquito gracias a vosotros.

Ahora me quedaría solventar esa línea.


Efectivamente, las clases estarían cada una en su propio fichero, este código es solo un ejemplo.

este es el resto del código:

Código C++:
Ver original
  1. //The setup function is called once at startup of the sketch
  2.  
  3. #include "Clase1.h"
  4.  
  5. Clase1 c1;
  6. Clase2 c2;
  7. void setup()
  8. {
  9.  c1 = Clase1();
  10.  c2 = Clase2();
  11.  
  12.  c1.setClase(&c2);
  13.  c2.setClase(&c1);
  14.  
  15.  
  16. }
  17.  
  18. void loop()
  19. {
  20.  
  21. }

Gracias por todo
  #7 (permalink)  
Antiguo 17/03/2016, 07:39
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 4 años, 10 meses
Puntos: 204
Respuesta: Problema con includes y clases una dentro de la otra

Código C++:
Ver original
  1. class Clase2;
  2.  
  3. class   Clase1 {
  4. public:
  5. Clase1(){};
  6.  
  7. void setClase(Clase2 * c ){c2 = c;}
  8.  
  9. void unaFuncion(){
  10. //idea 1
  11.     Clase2 c=*c2;//  ERROR
  12.      c.unaFuncion();
  13. };

Una pregunta tonta. ¿Has leído todo lo que te he puesto en la respuesta anterior? ¿Lo has entendido?

NO puedes usar un objeto por valor si no ha sido declarado previamente.

Huelga decir que tampoco es necesario eliminar un puntero para llamar a los miembros de una clase. Lo siguiente funcionaría sin problemas si el compilador conociese la declaración de Clase2:

Código C++:
Ver original
  1. c2->unaFuncion();

Nota que en el caso de punteros hay que usar la flecha en lugar del punto.

¿Posible solución? Fácil. Usa archivos de cabecera y de código o poner primero las declaraciones de las clases y después las implementaciones:

Código C++:
Ver original
  1. class Clase2;
  2.      
  3. class   Clase1 {
  4. public:
  5.     Clase1(){} // Los ; detrás de las llaves que cierran funciones no son necesarios
  6.      
  7.     void setClase(Clase2 * c ){ c2=c; }
  8.      
  9.     void unaFuncion();
  10.      
  11. private: // sugerencia
  12.     Clase2 * c2;
  13. };
  14.      
  15. class   Clase2 {
  16. public:
  17.     Clase2(){}
  18.      
  19.     void setClase(Clase1 * c ){c1 = c;}
  20.      
  21.     void unaFuncion(){
  22.         c1->unaFuncion();
  23.     }
  24.      
  25.     Clase1 * c1;
  26. };
  27.  
  28. // Llegados a este punto el compilador ya conoce la declaración de Clase2...
  29. void Clase1::unaFuncion()
  30. { c2->unaFuncion(); } // ...y esto pasa a ser legal

Por cierto, nota que si Clase1::unaFuncion llama a Clase2::unaFuncion y este a su vez llama a Clase1::unaFuncion el programa va a entrar en bucle y va a dejar de responder.

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.

Etiquetas: clases, includes
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 09:25.