[C con Clase] Problema al instanciar.. reconoce como no declarado

Steven Davidson steven en conclase.net
Dom Ene 14 16:07:04 CET 2007


Hola Manuel,

El pasado 2007-01-14 10:01:49, Manuel escribió:
 
M> Hola a todos, pues tengo un problema, mi aplicacion no reconoce una 
M> declaracion de una instancia de una clase, bueno:
M> main.cpp:
M> //----INCLUDES----//
M> #include <iostream>
M> #include "Sdl/SDL_ttf.h"
M> #include "Sdl/SDL_mixer.h"
M> #include "funciones.h"
M> //----VALORES----//
M> //Variables//
M> bool bucle= true;
M> //Sdl//
M> SDL_Surface* pantalla;
M> SDL_Event evento;
M> //Iniciacion//
M> void Inicializar(); /*AQUI DECLARO LA INSTANCIA*/
M> //----PROGRAMA----//
M> int main(int argc, char **argv)
M> {
M>  SDL_Init(SDL_INIT_VIDEO);
M>  pantalla= SDL_SetVideoMode(800,600,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
M>  while(bucle)
M>  {
M>   avion.Dibujar(pantalla); /*AQUI EL PROBLEMA*/
M> No reconoce la instancia "avion" y esta la hedeclarado en la funcion 
M> "inicializar" marcada en el codigo anterior, este es el codigo que posee 
M> la funcion inicializar:

Esto es lógico ya que 'avion' no ha sido declarado en este ámbito ni en uno superior. Por lo tanto, 'avion' no existe. También tienes que tener presente que al tener más de un fichero fuente, el compilador no "mira" a todos como una unidad. El compilador toma cada fichero fuente por separado, generando sus respectivos ficheros objetos. El enlazador es quien se encarga de reunir y agrupar dichos ficheros objetos bajo un mismo fichero.

M> funciones.cpp:
M> #include "funciones.h"
M> //Inicializar//
M> void Inicializar()
M> {
M>  CFotograma f_avion("Graficos/avion.bmp");
M>  CGrafico avion(1);
M>  avion.Insertar(f_avion);
M> }
M> Dudo que sea un problema de enlace, como veran "avion" esta declarado, 

Efectivamente, 'avion' se declara y se instancia aquí, pero su ámbito es local y por tanto aquí existirá hasta que se salga del ámbito. En dicho momento, todas las variables locales son destruidas automáticamente.

Esto es una cuestión básica de las reglas de ámbito en C++. Te pongo un ejemplo más claro para que veas el problema:

void func()
{
  int x = 10;
}

int main()
{
  func();
  x += 5;
  return 0;
}

Esto dará error, ya que 'x' bajo 'main()' no ha sido declarada. Es cierto que existe una variable 'x' en 'func()', pero no tiene absolutamente nada que ver con la 'x' en 'main()'.

La solución a tu problema es declarar e instanciar 'avion' en 'main()' y sdimplemente llevar a cabo las sentencias de 'Inicializar()' dentro de 'main()'. Si necesitas la función 'Inicializar()', entonces sugiero pasar un puntero del objeto 'avion' como parámetro. Por ejemplo,

void Inicializar( CGrafico *ptr )
{
  CFotograma f_avion( "Graficos/avion.bmp" );
  ptr->Insertar( f_avion );
}
...
int main()
{
  CGrafico avion( 1 );
  Inicializar( &avion );
  ...
}

También podrías pasar el objeto por referencia:

void Inicializar( CGrafico &ref )
{
  CFotograma f_avion( "Graficos/avion.bmp" );
  ref.Insertar( f_avion );
}
...
int main()
{
  CGrafico avion( 1 );
  Inicializar( avion );
  ...
}

De todos modos, para cuestiones de inicialización de objetos, tenemos el constructor. Podrías haber creado otra versión del constructor de la clase 'CGrafico' para aceptar como parámetro a un objeto de la clase 'CFotograma'. Por ejemplo,

CGrafico::CGrafico( int n, CFotograma foto )  {...}

Y luego, puedes hacer lo siguiente al instanciar el objeto 'avion':

int main()
{
  CFotograma f_avion( "Graficos/avion.bmp" );
  CGrafico avion( 1, f_avion );
  ...
}

O incluso,

int main()
{
  CGrafico avion( 1, CFotograma( "Graficos/avion.bmp" ) );
  ...
}


Espero haber aclarado la duda.

Steven


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