Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Compilación

Iniciado por player, 02 de Septiembre de 2010, 08:58:30 AM

« anterior - próximo »

player

Hola, me piden que haga algo un poco extraño, a ver si me podéis guiar un poco.

Tengo un fichero .h con una clase y sus métodos.

Luego tengo un fichero .cpp con varios prototipos de funciones, el desarrollo de esas funciones, 2 estructuras y algunas constantes.

Desde el .h, dentro de los métodos de la clase, tengo que hacer llamadas a esas funciones desarrolladas en el .cpp y utilizar esas constantes, entonces, como no están incluidas, el compilador me manda mensajes de error como que esas funciones no se han declarado.

Qué puedo hacer?

Gracias.

t-spy

Para hacer lo que quieres tienes que sacar la declaración de la clase que tienes en el .cpp a otro .h e incluirlo en el primero.

player

La declaración de la clase (y sus métodos) está en el .h, no en el .cpp

En el .cpp están los prototipos de las funciones y las funciones, junto al main y las estructuras y constantes

blau

no estoy yo muy puesto en c++, pero ¿no estaras hablando de hacer un include?  ^_^'

tamat

No me cuadra esto:

"Desde el .h, dentro de los métodos de la clase, tengo que hacer llamadas a esas funciones desarrolladas en el .cpp"

No has dicho que el cuerpo de las funciones estan en el CPP? entonces pueden llamar a las funciones que esten en dicho CPP (si estan definidas más arriba de ellas).

Si el cuerpo de las funciones está en el .H entonces tendras que definir el prototipo de las funciones del CPP tambien en el .H

Por un stratos menos tenso

player

#5
Cita de: blau en 02 de Septiembre de 2010, 11:40:06 AM
no estoy yo muy puesto en c++, pero ¿no estaras hablando de hacer un include?  ^_^'
A  ver...está bien que no tenga un nivel avanzado, pero no soy tonto..

Cita de: tamat en 02 de Septiembre de 2010, 12:32:36 PM
No me cuadra esto:

"Desde el .h, dentro de los métodos de la clase, tengo que hacer llamadas a esas funciones desarrolladas en el .cpp"

No has dicho que el cuerpo de las funciones estan en el CPP? entonces pueden llamar a las funciones que esten en dicho CPP (si estan definidas más arriba de ellas).

Si el cuerpo de las funciones está en el .H entonces tendras que definir el prototipo de las funciones del CPP tambien en el .H



Me piden que haga:

Yo tengo una librería .h con esto:

Definición de la clase
Métodos de la clase(dentro de los métodos se hacen llamadas a funciones del .cpp)

Tengo un .cpp con esto:

Constantes
Prototipos de funciones
Estructuras
Main
Desarrollo de las funciones

Al compilar, me da un error con razón, porque me dice que las funciones a las que estoy llamando desde el .h no están definidas (ya que sólo están en el .cpp) y también me dice que las constantes que utilizo dentro de los métodos no están definidas (porque están definidas en el .cpp) y también que las estructuras que utilizo dentro de los métodos no están definidas (porque sólo están en el .cpp).

Por eso preguntaba si hay alguna forma de hacer que funcione porque me piden que sea así tal cual y así tal cual no puede ser.

Yo lo tengo hecho de esta forma, pero me dicen que no es válido, porque en el .h sólo quieren la clase y los métodos de la clase y en el .cpp el resto de cosas, sin posibilidad de crear otra librería e incluirla en el .cpp.

En el .h tengo:

Constantes
Prototipos de funciones
Estructuras
Definición de la clase
Métodos de la clase(dentro de los métodos se hacen llamadas a funciones del .cpp)

En el .cpp tengo:

Main y desarrollo de funciones

Así al hacer el include del .h en el .cpp sí que me funciona y es la forma lógica que le encuentro (aunque el desarrollo de las funciones también las hubiera metido en la librería), pero no me dejan hacerlo así (un profesor muy inteligente es el que no lo quiere así).

Gracias.

tamat

entonces deduzco que nos pides ayuda para una practica de la carrera... ejem...

lo que te piden entonces es que aquellas cosas declaradas en el CPP tambien lo esten en el .H
Es decir, el cuerpo de las funciones puede estar en el CPP, pero tienes que dejar constancia en el .H de que existen, para ello declara los prototipos de las funciones y las constantes desde tu .H

Para las constantes creo que tienes que añadir  extern "C"  delante, para indicarle que en algun lugar del codigo existe una instancia de esa variable, pero sin crear la instancia en ese lugar (de lo contrario tendrias dos veces la variable, en el H y en el CPP).

Header:

void mifuncion();
extern "C" const int myvar;

//... codigo de la clase


CPP:

const int myvar = 10;

void mifuncion()
{
  //...
}





Por un stratos menos tenso

player

#7
Gracias tamat, ya veo que hay que declarar los prototipos y constantes en el .h, es lo lógico y lo que siempre he hecho, pero al decirme que está mal porque en el .h sólo quiere que aparezcan la clase y sus métodos y en el .cpp todo lo demás, he dudado de si había alguna otra manera de hacerlo.

Queda demostrado de nuevo que hay mucho incompetente en el mundo de la enseñanza.

Saludos y gracias.

tamat

es que lo correcto sería que en el .H no hubiera codigo, solo declaraciones, por algo se le llama cabecera.

entonces en el CPP defines el cuerpo de los metodos de la clase, y tus funciones y constantes. si lo haces así no es necesario que en el .H definas los prototipos de las funciones ya que las funciones estan accesibles al ser el mismo fichero (como mucho tal vez tengas que ponerlas mas arriba en el .CPP)
Por un stratos menos tenso

The_Dragon_Ladis

Un ejemplillo así tonto sacado de una practica de la carrera al azar.

Fichero .h
#ifndef ARCHIVOS_H_
#define ARCHIVOS_H_

int almacena_piezas(tpieza *p,int tam,char *ruta);
int recupera_piezas1(char *ruta,tpieza *p,int tam);
int numero_piezas_archivo(char *ruta);
tpieza* recupera_piezas2(char *ruta,int *plongitud);
int concatena_piezas_archivo(tpieza *p,int tam,char *ruta);



#endif /* ARCHIVOS_H_ */


Fichero .c
#include "pieza.h"
#include <stdio.h>
#include <stdlib.h>
/*
* @brief Guarda en un fichero binario el vector pasado
* @param p Vector a guardar
* @param tam Tamaño del vector
* @param ruta Ruta donde guardar el archivo
* @return Devuelve el numero de elementos guardados o 0 si error
*/
int almacena_piezas(tpieza *p,int tam,char *ruta)
{
int numPiezas;

FILE *file;

file=fopen(ruta,"wb");

if(file==NULL)
{
numPiezas=0;
}else
{
numPiezas=fwrite(p,sizeof(tpieza),tam,file);

if(numPiezas!=tam)
{
numPiezas=0;
}
}

fclose(file);

return numPiezas;
}

/*
* @brief Carga piezas desde un archivo
* @param ruta Ruta donde se encuentra el archivo con los datos
* @param p Vector donde almacenar los elementos cargados
* @param tam Tamaño del vector y numero de elementos que cargaremos desde el archivo
* @return Devuelve el numero de elementos leidos o 0 si hubo error
*/
int recupera_piezas1(char *ruta,tpieza *p,int tam)
{
int numPiezas;
FILE *file;

file=fopen(ruta,"rb");

if(file==NULL)
{
numPiezas=0;
}else
{
numPiezas=fread(p,sizeof(tpieza),tam,file);

if(numPiezas!=tam)
{
numPiezas=0;
}
}

fclose(file);

return numPiezas;
}

/*
* @brief Calcula el numero de elementos pieza que tiene un archivo
* @param ruta Ruta donde se encuentra el archivo
* @return Devuelve el numero de piezas contenidas en el archivo
*/
int numero_piezas_archivo(char *ruta)
{
int num;

FILE *file;

if((file=fopen(ruta,"rb"))==NULL)
{
fprintf(stderr,"\nnumPiezasArchivo:error al abrir el archivo");
}else
{
fseek(file,0,SEEK_END);

num=(int)ftell(file)/sizeof(tpieza);
}

fclose(file);

return num;
}

/*
* @brief Carga todos los clientes de un archivo
* @param ruta Ruta donde se encuentra el archivo con la informacion
* @param plongitud Numero de elementos que tendra el vector (y por tanto que hay en el archivo)
* @return Devuelve un vector con los elementos del archivo
* @post Modifica plongitud con el numero de elementos que hay en el vector
*/
tpieza* recupera_piezas2(char *ruta,int *plongitud)
{
tpieza *nuevo;
int error;
FILE *file;

(*plongitud)=numero_piezas_archivo(ruta);

if((nuevo=(tpieza*)malloc(sizeof(tpieza)*(*plongitud)))==NULL)
{
fprintf(stderr,"\nrecuperaPiezas2:no hay memoria.\n");
}

if((file=fopen(ruta,"rb"))==NULL)
{
fprintf(stderr,"recuperaPiezas2:error al abrir el archivo.\n");
}else
{
if(fread(nuevo,sizeof(tpieza),(*plongitud),file)!=(*plongitud))
{
error=ferror(file);
if(error)
{
//fprintf(stderr,"\n%s\n",strerror(error));
nuevo=NULL;
}
}
}

fclose(file);


return nuevo;
}

/*
* @brief Inserta al final del archivo todos los elementos de un vector
* @param p Vector con las piezas a guardar en el archivo
* @param tam Tamaño del vector
* @param ruta Ruta donde se encuentra el archivo donde se guardara la informacion
* @return Devuelve el numero de elementos guardados
*/
int concatena_piezas_archivo(tpieza *p,int tam,char *ruta)
{
int numPiezas;
FILE *file;

if((file=fopen(ruta,"wb"))==NULL)
{
fprintf(stderr,"\nconcatenaPiezasArchivo:no se pudo abrir el archivo.\n");
}else
{
fseek(file,0,SEEK_END);
numPiezas=fwrite(p,sizeof(tpieza),tam,file);

if(numPiezas!=tam)
{
fprintf(stderr,"\nconcatenaPiezasArchivo:error al escribir en el archivo.\n");
numPiezas=0;
}
}

return numPiezas;
}



Luego ya puedes tener otro fichero main.c (por poner un nombre) con tu función main. Con incluir el archivo de cabecera .h tendras disponibles las funciones que has declarado.

Piensa en ello como si fueran en parejas. fichero.c y fichero.h. El fichero.c declaras tus funciones, como funcionan y lo que hacen, es los engranajes por así decirlo. En el .h pones solo la cabecera de cada función que quieras que este accesible desde fuera cuando hagas un #include . Lo suyo es que también declares aquí los tipos y estructuras para tenerlos también disponibles donde hagas un #include.

Espero haberme explicado.


player

Gracias por los ejemplos y explicaciones.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.