¿Es mejor usar static const
vars que #define
preprocesador? ¿O tal vez depende del contexto?estática const vs #define
¿Cuáles son las ventajas/desventajas de cada método?
¿Es mejor usar static const
vars que #define
preprocesador? ¿O tal vez depende del contexto?estática const vs #define
¿Cuáles son las ventajas/desventajas de cada método?
Personalmente, detesto el preprocesador, por lo que siempre iría con const.
La principal ventaja de un #define es que no requiere memoria para almacenar en su programa, ya que simplemente está reemplazando algún texto con un valor literal. También tiene la ventaja de que no tiene ningún tipo, por lo que se puede usar para cualquier valor entero sin generar advertencias.
Las ventajas de "const" s son que pueden ser delimitadas, y se pueden usar en situaciones donde se necesita pasar un puntero a un objeto.
Sin embargo, no sé exactamente qué es lo que está consiguiendo con la parte "estática". Si declaras globalmente, lo pondría en un espacio de nombre anónimo en lugar de usar estática. Por ejemplo
namespace {
unsigned const seconds_per_minute = 60;
};
int main (int argc; char *argv[]) {
...
}
Eso es lo que quiero saber. En mi compañía, la estrategia es poner todas las cadenas constantes como #define en un archivo separado. Estaba pensando que puede ser mejor usar const vars en su lugar. Gracias –
* Las constantes de String * específicamente son una de las que podrían beneficiarse de ser '# define'd, al menos si se pueden usar como" bloques de construcción "para las constantes de cadena más grandes.Ver mi respuesta para un ejemplo. – AnT
Un caso que no había considerado. Gracias por tu tiempo. –
Usar una constante estática es como usar cualquier otra variable constante en su código. Esto significa que puede rastrear desde donde proviene la información, a diferencia de un #define que simplemente se reemplazará en el código en el proceso de precompilación.
Es posible que desee echar un vistazo a la C++ FAQ Lite para esta pregunta: http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.7
favor ver aquí: static const vs define
por lo general una declaración const (nótese que no tiene por qué ser estática) es el camino a seguir
Si se trata de una cuestión de C++ y menciona #define
como alternativa, a continuación, se trata de constantes (es decir, el archivo de alcance mundial) "", no sobre miembros de la clase. Cuando se trata de tales constantes en C++ static const
es redundante. En C++ const
tienen un enlace interno por defecto y no tiene sentido declararlos static
. Entonces realmente se trata de const
contra #define
.
Y, finalmente, en C++ const
es preferible. Al menos porque tales constantes son mecanografiadas y delimitadas. Simplemente no hay razones para preferir #define
sobre const
, salvo algunas excepciones.
Las constantes de cadena, por cierto, son un ejemplo de esta excepción. Con #define
constantes d de cadena se puede utilizar en tiempo de compilación característica concatenación de los compiladores de C/C++, como en
#define OUT_NAME "output"
#define LOG_EXT ".log"
#define TEXT_EXT ".txt"
const char *const log_file_name = OUT_NAME LOG_EXT;
const char *const text_file_name = OUT_NAME TEXT_EXT;
P.S. De nuevo, por si acaso, cuando alguien menciona static const
como alternativa al #define
, generalmente significa que están hablando de C, no de C++. Me pregunto si esta pregunta se etiqueta correctamente ...
Por lo general, debería preferir las constelaciones estáticas.No tiene ninguna desventaja. El procesador debe usarse principalmente para la compilación condicional (y, a veces, para trucos realmente sucios).
Pros y contras de todo, dependiendo del uso:
enum class X
son desambiguadas por el alcance X::
int
pero puede establecerlo explícitamente el programadortemplate <typename T> void f(T t) { cout << ++t; }
no se compilará, aunque se puede envolver una enumeración en una clase con el constructor implícito, fundición operador y operadores definidos por el usuario)template <typename T> void f(T)
obtener una ejemplificación distinta cuando se pasa el mismo valor numérico de diferentes enumeraciones, todas las cuales son distintas de cualquier instanciación real de f(int)
. El código objeto de cada función podría ser idéntico (ignorando los desplazamientos de dirección), pero no esperaría que un compilador/enlazador elimine las copias innecesarias, aunque podría verificar su compilador/vinculador si lo desea.enum { A = 1, B = 2 }
- es A|B
"legal "¿desde una perspectiva lógica de programa?)make
y otras herramientas de recompilación basadas en la marca de tiempo desencadenarán la recompilación del cliente cuando se cambien (¡mal!)#define
ala #define S std::string("abc")
, pero las evita constantes construcción repetida de temporales distintos en cada punto de usoconst
, lo que minimiza el trabajo y el impacto si el cambio entre el valor de dos#define X "x"
y algo de uso del cliente ala "pre" X "post"
, si desea o necesita hacer X una variable de tiempo de ejecución modificables en lugar de una constante se fuerza ediciones en código de cliente (en lugar de simplemente recompilar), mientras que esa transición es más fácil desde un const char*
o const std::string
dado que ya fuerzan al usuario a incorporar el concat operaciones de enación (p. "pre" + X + "post"
para string
)sizeof
directamente en una definida numérico literalunsigned
){ 1, 2 }
que se pueden utilizar para inicializar matrices, o #define MICROSECONDS *1E-6
, etc. ( definitivamente no recomendar este!)__FILE__
y __LINE__
se pueden incorporar en la sustitución de macro#if
declaraciones para la inclusión de código de forma condicional (más potente que un post- preprocesamiento "si" ya que el código no necesita ser compilable si no es seleccionado por el preprocesador), use #undef
-ine, redefina, etc.make
y otras herramientas de recompilación basada en fecha y hora se activará recompilación cliente cuando que se cambia (mal)Como regla general, uso const
sy los considero la opción más profesional para el uso general (aunque los otros tienen una simplicidad que atrae a este viejo programador perezoso). No se recomienda
+1: aprecia su resumen – Chubsdad
Awesome answer. Una pequeña queja: a veces uso enumeraciones locales que no están en los encabezados en absoluto solo por la claridad del código, como en las máquinas de estado pequeño y demás. Por lo tanto, no tienen que estar en los encabezados, en todo momento. – kert
@kert: punto sólido ... editado en consecuencia. Gracias. –
constantes que definen mediante el uso de directiva de preprocesador #define
aplicar no sólo en C++
, sino también en C
. Estas constantes no tendrán el tipo. Incluso en C
se propuso utilizar const
para las constantes.
Si está definiendo una constante para compartir entre todas las instancias de la clase, use const estático. Si la constante es específica para cada instancia, simplemente use const (pero tenga en cuenta que todos los constructores de la clase deben inicializar esta variable miembro miembro en la lista de inicialización).
Siempre prefiera usar las funciones de idioma sobre algunas herramientas adicionales como el preprocesador.
ES.31: No usar macros para las constantes o "funciones"
macros son una fuente importante de errores. Las macros no obedecen el alcance habitual y las reglas de tipo. Las macros no obedecen las reglas habituales para el argumento que pasa. Las macros garantizan que el lector humano vea algo diferente según lo que ve el compilador. Las macros complican la construcción de herramientas.
Scott Meyers cubre este tema muy bien ya fondo. Su artículo n. ° 2 en "Eficaz tercera edición de C++". Se prefieren dos casos especiales (1) const estático dentro de un alcance de clase para constantes específicas de clase; (2) espacio de nombres o const de alcance anónimo con preferencia sobre #define. – Eric
Prefiero Enumerar. Porque es híbrido de ambos. No ocupa espacio a menos que crees una variable del mismo. Si solo quieres usar como constante, enum es la mejor opción. Tiene seguridad de tipo en C/C++ 11 std y también una constante perfecta. #define es tipo inseguro, const toma espacio si el compilador no puede optimizarlo. – siddhusingh
Mi decisión de usar '# define' o' static const' (para cadenas) es manejada por el aspecto ** initialization ** (no se mencionó a través de las respuestas a continuación): si se usa constant solo en una unidad de compilación particular, entonces Voy con 'static const', de lo contrario utilizo' # define' - evito la inicialización de orden estática ** fiasco ** https://isocpp.org/wiki/faq/ctors#static-init-order –