[C con Clase] duda con #defines
Steven Davidson
steven en conclase.net
Jue Jun 21 06:58:30 CEST 2007
Hola Pamela,
El pasado 2007-06-21 03:56:06, Pato escribió:
P> Bien, muchas gracias Steven, muy clara tu explicación.
De nada; para eso estamos.
P> La duda que me surge es que he leído que el uso de macros no permite
P> la 'revisión de tipos' en el libro de Deitel, eso me sugiere que hay
P> una mejor forma de hacer lo mismo. La pregunta sería ¿cual es la
P> ventaja de hacerlo con esas macros complejas? ¿hay forma de hacerlo
P> más legible o portable aunque se pierda eficiencia?
Ciertamente, no es conveniente usar macros ni constantes simbólicas si podemos usar funciones y constantes, respectivamente. C++ introduce ciertos "mecanismos" o técnicas para usar el lenguaje para programar y no depender tanto de las directivas del precompilador.
Las constantes simbólicas pueden ser sustituidas por constantes. Por ejemplo,
#define NMAX 100
#define BUFTAM (1024*NMAX)
...
int *pLista = new int[NMAX];
Bajo C++, se puede reescribir lo anterior como:
const int NMAX = 100;
const int BUFTAM = 1024*NMAX;
...
int *pLista = new int[NMAX];
Para las macros, podemos usar funciones "en línea" o "in situ". Por ejemplo,
#define max(a,b) ((a) > (b) ? (a) : (b))
Bajo C++, escribimos:
inline int max( int a, int b )
{
return a > b ? a : b;
}
Si queremos aceptar cualquier tipo de dato para los dos parámetros, entonces podemos usar funciones plantillas. Esto sería:
template< typename T >
inline T max( T a, T b )
{
return a > b ? a : b;
}
Ahora podemos usar 'max()' con cualquier tipo de dato, con tal de que exista una definición para el operador > con este tipo de dato. Por ejemplo,
cout << max( 10, 200 );
cout << max( 1.23e10, .2034e-6 );
cout << max( 123123123L, 4549830912L );
Esto no significa que las macros y constantes simbólicas no se usen, sino que a la hora de programar, no tenemos que depender de ellas, si no son necesarias. Por ejemplo,
#ifndef _FICHERO_H_
#define _FICHERO_H_
#include <iostream>
#ifndef _VERSION_
#define _VERSION_ 0x0402
#endif
#define _ID_ #__FILE__ ";" #_VERSION_ ";" #__TIMESTAMP__
#endif
Lo anterior sería bastante engorroso si no usáramos el precompilador. Claro que podríamos reescribir la última constante simbólica como una constante, pero no su definición. Es decir,
const char _ID_[] = #__FILE__ ";" #_VERSION_ ";" #__TIME__;
Después del precompilador, acabaríamos con un código fuente como el siguiente:
const char _ID_[] = "fichero.h" ";" "0x0402" ";" "16:28:45";
que es lo mismo que,
const char _ID_[] = "fichero.h;0x0402;16:28:45";
Las macros también pueden sernos de mucha ayuda, pero si se puede describir su comportamiento como una función de C++, entonces escribe el código en C++.
Espero que todo esto te sirva.
Steven
Más información sobre la lista de distribución Cconclase