[C con Clase] Consejo donde definir clases

Steven Davidson srd4121 en njit.edu
Lun Ene 10 00:53:51 CET 2011


Hola Jorge,

On 1/7/11, Jorge Vega Sanchez <memmaker650 en gmail.com> wrote:
> Bueno vuelvo a la carga porque como buen zoquete tengo problema al compilar
> una clase.
>
> La clase está creada con templates para hacerla más genérica.
> La cosa es que si lo hago en todo en un mismo fichero me funciona todo
> perfectamente pero ahora lo he divido en 3 ficheros ( 2 para la clase y el
> principal) y me compila pero no me enlaza. Al enlazar me dice que los
> métodos de clase no están definidos.
>
> Undefined symbols:
>   "almacen<int>::almacen(int)", referenced from:
>       _main in main.o
>   "almacen<int>::meter(int)", referenced from:
>
>
>
>
> Si alguien pudiera decirme que hago mal se lo agradecería mucho porque llevo
> 2 horas tocando cosas al tun tun y al final voy a fastidiar más que
> arreglar.
>

El problema es que se trata de una plantilla y no de una clase. Las
plantillas no son compiladas, por lo que el enlazador no tiene nada
que ver con ellas. El compilador usa la plantilla para generar
(escribir) una clase y sus miembros. En este caso, sí hay código
compilado y por tanto el enlazador puede tratarlo.

La solución a tu problema es escribir la definición de la plantilla
íntegramente en un fichero de cabecera. Por motivos de organización,
sí podrías separar el diseño de la clase-plantilla de su
implementación en diferentes ficheros, pero el fichero de cabecera que
vayas a usar DEBE #incluir el otro fichero que contiene la
implementación. Por ejemplo,

// "a.h"

#ifndef _A_H_
  #define _A_H_

template< typename T >
class A
{
private:
  T obj;

public:
  A();
  A( const A &ref );
  ~A();

  T dato() const;
  T &dato();
};

  // incluimos la implementación de A
  #include "a.tcpp"

#endif


// "a.tcpp"

template< typename T >
A< T >::A()
{...}

template< typename T >
A< T >::A( const A &ref )
{...}

template< typename T >
A< T >::~A()
{...}

template< typename T >
T A< T >::dato() const
{...}

template< typename T >
T &A< T >::dato()
{...}


Como puedes ver, "a.h" #incluye el fichero "a.tcpp" que contiene la
implementación de la clase-plantilla. No es necesario separar la
definición de la plantilla en diferentes ficheros, pero sí ayuda en la
organización del proyecto.


Espero haber aclarado la duda.

Steven




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