Buenas Tengo 2 clases que me están dando problemas y es por el modo de declaración, aun no se como resolverlo si alguien sabe por favor ayude me...
Esto tiene un archivo
#include "Conectividad.hpp"
#ifndef _SOCKET_CPP
#define _SOCKET_CPP
class Socket{
private:
Host *host;
public:
Receiver *receiver;
Sender *sender;
Conectividad *conectividad;
public:
Socket(Host*);
};
Socket::Socket(Host*pHost){
this->host = pHost;
this->receiver = new Receiver(this->host);
this->sender = new Sender(this->host);
this->conectividad = new Conectividad(this->host);
}
Esto tiene el otro archivo
#ifndef _CONECTIVIDAD_CPP
#define _CONECTIVIDAD_CPP
class Socket;
class Conectividad {
private:
Host *host;
public:
Conectividad(Host*,int);
bool Bind();
bool Listen(int);
Host Accept();
bool Connect();
Socket Acceptar();
};
Socket Conectividad::Accept(){
//Variables
int addrlen = sizeof(sockaddr_in); // Tamaño
Host HostEstructura; // Return
// Acepta la Conexion
HostEstructura.setSocket( accept(host->getSocket(), (sockaddr*)HostRetorno.getSockAddress(), (socklen_t*)&addrlen ) );
Socket SocketRetorno(HostEstructura);
return HostEstructura;
}
#endif
El Error es este:
Citar
does not name a type error in C++
Ahora si, El problema se da en el segundo archivo, el primero tiene todo bien pero cuando intento implementar el método Accept y que me retorne un Socket me tira ese error... también es porque intento llamar el constructor de Socket si haber implementado la clase completa pero es que no puedo hacer un include de Socket dentro del segundo archivo ya que me rebota, porque ya hice un #include "Conectividad.hpp" en Socket y no se porque sucede....
Alguna sugerencia??
Host Accept();
La función devuelve un Host pero la has implementado como que devuelve un Socket.
Por otro lado, la implementación debería ir en un fichero .cpp, las definiciones en un fichero .hpp y estas se incluyen mutuamente. No tienes que hacer cosas como esta:
class Socket;
Que no estoy muy seguro que funcione bien (el compilador no puede saber que miembros tiene Socket desde el otro fichero cpp).
Si están implementadas de forma separada en ficheros .cpp y .hpp, pero aquí lo agrego pegado porque son muchos muchos métodos.. entonces solo estoy pegando donde esta el problema.
Siento mucho ese error del return queda
Socket SocketRetorno(HostEstructura);
return SocketRetorno;
}
El problema es que si elimino esta linea:
class Socket;
Me da mas problemas, esto se debe a que No esta incluido el fichero de Socket.hpp en el Connectividad.cpp, pero si lo incluyo me da problemas y si no lo incluyo también, como puede ver del lado de la clase Socket.cpp si esta incluido el fichero "Conectividad.hpp", el problema es con el método Accept() que tiene que devolver un objeto tipo socket pero... como obtiene la clase socket si no ha sido declarada y no se puede incluir
Ah vale.
No deberías darte problemas el include siempre que lo pongas dentro del protector (ahí lo tienes fuera)
Con protector me refiero a:
#ifndef _SOCKET_CPP
#define _SOCKET_CPP
http://stackoverflow.com/questions/2133250/does-not-name-a-type-error-in-c
Hay en esa pagina tiene un problema similar al mio, lo resuelve pero... no presenta el problema que yo tengo ya que yo trato de retornar la clase he usar el constructor...
Los includes están dentro y bien los he probado de todas formas y nada...
Bueno Ahora solo me esta dando error en el método:
Socket Conectividad::Accept(){
//Variables
int addrlen = sizeof(sockaddr_in); // Tamaño
Host HostEstructura; // Return
// Acepta la Conexion
HostEstructura.setSocket( accept(host->getSocket(), (sockaddr*)HostEstructura.getSockAddress(), (socklen_t*)&addrlen ) );
Socket SocketRetorno(&HostEstructura);
return SocketRetorno;
}
Este es el error que me da
Citar
Lib/Socket/Conectividad.hpp:25:29 return type 'struct Socket' is incomplete
Lib/Socket/Conectividad.gpp:33:22 variable 'Socket SocketRetorno' has initializer but incomplete type
Compilation fail.
La clase socket no tiene constructor copia.
Creo que lo más sencilo es que hagas esto:
Socket* Conectividad::Accept(){ // Puntero
//Variables
int addrlen = sizeof(sockaddr_in); // Tamaño
Host HostEstructura; // Return
// Acepta la Conexion
HostEstructura.setSocket( accept(host->getSocket(), (sockaddr*)HostEstructura.getSockAddress(), (socklen_t*)&addrlen ) );
Socket* SocketRetorno = new Socket(&HostEstructura);
return SocketRetorno;
}
Aunque en mi opinión, creo que es más práctico hacer un constructor adicional en la clase Socket con estos datos.
Ya lo he implementado pero me da otro error:
Citar
Lib/Socket/Conectividad.hpp:33:52: error: invalid use of incomplete type 'struct Socket'
Lib/Socket/Conectividad.hpp:6:7: error: forward declaration of 'struct Socket'
Que podría ser eso
Cita de: <<<-Underwar->>> en 5 Junio 2013, 00:52 AM
Ya lo he implementado pero me da otro error:
Que podría ser eso
Eliminastes lo de class socket;?
Estoy un poco extrañado, normalmente todo esto es algo mecánico y rutinario.
Mira para Tratar de resolverlo he hecho un código sin sentido pero útil que simula lo que esta pasando, tengo 2 fichero A.hpp y B.hpp
A.hpp:
#include "B.hpp"
#ifndef _A_
#define _A_
class A{
private:
B* b;
public:
A(int);
A(B*);
};
A::A(int algo){
b = new B(algo);
}
A::A(B *pB){
b = pB;
}
#endif
B.hpp:
//#include "A.hpp"
#ifndef _B_
#define _B_
//class A;
class B{
private:
int dato;
public:
B(int);
//A* retornoA();
};
B::B(int algo){
dato = algo;
}
/*
A* B::retornoA(){
A *a = new A(10);
return a;
}
*/
#endif
main:
#include "A.hpp"
int main(){
return 0;
}
Como puedes ver en "B.hpp", tiene cosas comentadas, esa es la forma que tenía el código antes de que surgiera el problema...
Citar
Lo que tienes que hacer.. es descomentar lo que veas que es necesario.
Estoy usando el IDE geany en linux
El compilador g++
Vale lo he estado probado y tienes razón.
El problema es el orden de la cabeceras, ambas clases se complementan pero al incluirse forman un bucle recursivo.
He conseguido compilar lo siguiente:
A.hpp
#ifndef A_H
#define A_H
class A
{
public:
A(int);
protected:
private:
int num;
B* Algo;
};
#endif // A_H
A.cpp
#include "B.h"
#include "A.h"
A::A(int n)
{
num = n;
Algo = new B;
}
B.hpp
#ifndef B_H
#define B_H
class A;
class B
{
public:
B();
protected:
private:
int tonteria;
A* retornoA();
};
#endif // B_H
B.cpp
#include "B.h"
#include "A.h"
B::B()
{
tonteria = 2;
}
A* B::retornoA(){
A *a = new A(10);
return a;
}
Main.cpp
#include <iostream>
#include "B.h"
#include "A.h"
using namespace std;
int main()
{
cout << "Hello world!" << endl;
return 0;
}
Hay otro método que proponen aquí:
http://www.daniweb.com/software-development/cpp/threads/20494/c-beginner-include-recursion-problem
Gracias por toda la ayuda que me brindastes ya lo he solucionado!!.
Basándome en lo ultimo que publicaste, se que hay que separar todo en *.hpp y *cpp pero no lo he hecho así ya que llega tornarse enorme para buscar un problema, también la solución que me brindaste no es la que andaba buscando. la de en el main tener que incluir las dos librerías:
#include "B.h" // Esto es lo que estaba evitando
#include "A.h" // Esto es lo que estaba evitando
int main(){
return 0;
}
Y esta es la solución:
A.hpp:
#include "B.hpp"
#ifndef _A_
#define _A_
class A{
private:
B* b;
public:
A(int);
A(B*);
};
A::A(int algo){
b = new B(algo);
}
A::A(B *pB){
b = pB;
}
#endif
B.hpp:
#ifndef _B_
#define _B_
class A;
class B{
private:
int dato;
public:
B(int);
A* retornoA();
};
B::B(int algo){
dato = algo;
}
#include "A.hpp"
A* B::retornoA(){
A *a = new A(10);
return a;
}
#endif
Y en el main incluyo solo a A.hpp
#include "A.hpp"
int main(){
return 0;
}
amchacon muchas gracias por ayudarme, fuiste de muy gran ayuda, de toda la gente que ayudo(nadie mas), espero que mi solución te sea de feedback,
Grafcias