[C con Clase] Error al compilar cuando paso a una función un parametro que de clase Cola definida por mi

Steven Davidson srd4121 en njit.edu
Vie Abr 27 20:35:48 CEST 2012


Hola Redondo,

On 4/27/2012 1:06 PM, redondo.af wrote:
> Buenas tardes a todos:
>
> Al compilar el programa que a continuación os muestro lo hace
> correctamente, pero cuando cambio la llamada a la función:
>
>         tratarOpcionCola(opsub)  por  tratarOpcionCola(opsub,Cola); (main.cpp)
>
>         void tratarOpcionCola(int op){ }   por
>         void tratarOpcionCola(int op, cola vlCola){ }   (procesos.cpp)
>
>         void tratarOpcionCola(int a) por
>         void tratarOpcionCola(int a,cola b);    (procesos.h)
>
>
> al compilar aparecen los siguientes errores:
>
> \procesos.h     `cola' has not been declared
> \main.cpp       In function `int main(int, char**)'cannot convert `cola' to
>                  `int' for argument `2' to `void tratarOpcionCola(int, int)'
>

Veamos el error.

>
> *******************************************************************************
>                                PROGRAMA
> *******************************************************************************
>
> *********main.cpp****************
>
> #include<cstdlib>
> #include<iostream>
> #include<string>
> using namespace std;
>
>
> #include "procesos.h"
> #include "clsCola.h"
>

Aquí tenemos un problema, pero es por culpa del diseño que has hecho. Si 
inviertes el orden de inclusión de estos ficheros, debería funcionar; 
esto es,

#include "clsCola.h"
#include "procesos.h"

Esto implica que el resultado es el siguiente:

class nodo {
    public:
...
};

class cola {
...
};

int mostrarMenuMain();
int mostrarMenuCola();
//void tratarOpcionCola(int a,cola b);
void tratarOpcionCola(int a);

Recuerda que C++ lee de arriba a abajo y de izquierda a derecha. Tal y 
como lo tenías escrito, estabas usando 'cola' sin haber definido esta 
entidad y por tanto el compilador se queja.

La solución más elegante y práctico es rediseñar el fichero de cabecera, 
"procesos.h", para que funcione correctamente irrelevantemente del orden 
de inclusión en un proyecto. Lo explico más abajo.

>

[CORTE]

> ***************procesos.cpp************************************
>
> #include<string>
> using std::string;
> #include<iostream>
> using std::cin;
> using std::cout;
>

Debes incluir <cstdlib>, ya que usas 'system()' y <cstdio> para 'printf()'.

> #include "procesos.h"
> #include "clsCola.h"
>

Aquí tienes el mismo problema. Puedes invertir las inclusiones, pero no 
lo aconsejo.

>

[CORTE]

>
> ************************procesos.h***************
>
> int mostrarMenuMain();
> int mostrarMenuCola();
> //void tratarOpcionCola(int a,cola b);
> void tratarOpcionCola(int a);
>

Al necesitar la definición de 'cola', este fichero de cabecera requiere 
la inclusión de "clsCola.h". Haciendo esto, obtenemos,

#include "clsCola.h"

int mostrarMenuMain();
int mostrarMenuCola();
void tratarOpcionCola(int a,cola b);
void tratarOpcionCola(int a);


Sin embargo, es posible que tengas problemas de definiciones repetidas 
debidos a las inclusiones repetidas, como puede ser en "main.cpp" y en 
"procesos.cpp", ya que escribes:

#include "procesos.h"
#include "clsCola.h"

Incluyes "procesos.h" y luego incluir "clsCola.h", pero este fichero se 
incluyó en "procesos.h" previamente. El compilador verá esto:

// inclusión de "procesos.h"
class nodo {
...
};

class cola {
...
};

int mostrarMenuMain();
int mostrarMenuCola();
void tratarOpcionCola(int a,cola b);

// inclusión de "clsCola.h"
class nodo {
...
};

class cola {
...
};

Como puedes ver repites la inclusión de "clsCola.h".

La solución a estas inclusiones repetidas, en C/C++, es usar las 
directivas del precompilador. Por ejemplo,

// "clsCola.h"

#ifndef CLSCOLA_H
#define CLSCOLA_H

class nodo {
...
};

class cola {
...
};

#endif

// "procesos.h"

#ifndef PROCESOS_H
#define PROCESOS_H

#include "clsCola.h"

int mostrarMenuMain();
int mostrarMenuCola();
void tratarOpcionCola(int a,cola b);
void tratarOpcionCola(int a);

#endif

De esta manera, sólo incluimos el contenido de cada fichero de cabecera 
una sola vez. Algunos compiladores aceptan el parámetro "once" para la 
directiva #pragma para realizar la misma tarea; esto es,

// "clsCola.h"

#pragma once

class nodo {
...
};

class cola {
...
};


// "procesos.h"

#pragma once

#include "clsCola.h"

int mostrarMenuMain();
int mostrarMenuCola();
void tratarOpcionCola(int a,cola b);
void tratarOpcionCola(int a);

Pero este parámetro no es estándar.


Por último, quiero comentar que no es una buena opción aceptar un objeto 
como parámetro, ya que crearás una copia del objeto a pasar. Recuerda 
que los parámetros se pasan por copia. En tu caso, no necesitas una 
copia, y además, no funcionaría correctamente, porque no has definido un 
constructor copia para 'cola'.

La solución es pasar el objeto por referencia; si no quieres 
modificarlo, entonces indica que es 'const'. Esto sería,

void tratarOpcionCola( int a, const cola &b );

También usas 'printf()', cuando has incluido <iostream> e indicas que 
vas a usar 'cout' y 'cin'.


Espero haber aclarado las dudas.

Steven





Más información sobre la lista de distribución Cconclase