[C con Clase] sobre #

Steven Davidson srd4121 en njit.edu
Jue Oct 16 19:25:52 CEST 2008


Hola Pedro,

Pedro Mateo wrote:
> hola a todos
> tengo la siguiente plantilla
>  
> template<typename DATA,const bool borrar_en_destructor=false>
> class claseX{
>       DATA data; 
>       public:
>       claseX(const DATA& x):data(x){}
>       ~claseX(){
>               #if borrar_en_destructor==true
>                      delete data;
>               #endif
>        }
>       
> }
>  
> como DATA puede ser cualquier tipo, pero si es un puntero puede darse
> el caso de que yo desee que la clase le de un delete al puntero al
> ser destruida la instancia
>  
> el codigo que he propuesto no funciona y me gustaria saber si estoy 
> haciendo algo que no se puede o estoy haciendo algo mal
>  

Efectivamente, tienes un error gramatical que está aquí:

#if borrar_en_destructor==true

Ten presente que # implica una directiva del precompilador y por tanto 
la expresión que sigue debe poder ser evaluado por el precompilador. La 
cosntante 'borrar_en_destructor' pertenece a C++ y no existe como tal en 
la precompilación; o sea, el precompilador no entiende lo que es 
'borrar_en_destructor'. Podrías usar 'if' del lenguaje de C++ y no su 
homólogo, la directiva del precompilador #if. Esto es,

~claseX()
{
   if( borrar_en_destructor )  delete data;
}


De todas maneras, no sugiero implementar este código de esta manera. En 
su lugar, define plantillas parcialmente especializadas. Como el 
problema es que el tipo de dato puede ser un puntero, entonces sugiero 
crear tal especialidad parcial. Esto es,

template< typename DATA >
class claseX
{
   DATA data;
public:
   claseX( const DATA& x ) : data(x)  {}
   ~claseX()  {}
};

template< typename DATA >
class claseX< DATA * >
{
   DATA *data;
public:
   claseX( const DATA* x ) : data(0)
   {
     data = new DATA;
     *data = DATA(0);  // Asignamos 0 al 'DATA' apuntado
   }
   ~claseX()
   {
     delete data;
   }
};


Si usamos un tipo de dato que es un puntero, entonces usamos la 
especialización parcial que hemos creado. Si el tipo del dato del 
argumento de la plantilla no es un puntero, entonces usamos la 
definición de la plantilla general.


Espero que esto te sirva.

Steven





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