Lo sé para evitar la inclusión múltiple del archivo de encabezado. Pero supongamos que me aseguro de incluir este archivo en solo un archivo .cpp solo una vez. ¿Todavía hay escenarios en los que necesitaría esta protección?Propósito de #ifndef FILENAME .... # endif en el archivo de encabezado
Respuesta
Puede garantizar que su código sólo incluye una vez, pero se puede garantizar que el código cualquiera 's incluirá una vez?
Por otra parte, imaginar esto:
// a.h
typedef struct { int x; int y; } type1;
// b.h
#include "a.h"
typedef struct { type1 old; int z; } type2;
// main.c
#include "a.h"
#include "b.h"
Oh, no! Nuestra main.c
solo incluyó una vez, pero b.h
incluye a.h
, por lo que obtuvimos a.h
dos veces, a pesar de nuestros mejores esfuerzos.
Ahora imagine esta escondido detrás de tres o más capas de #include
s y es un menor uso interno de sólo encabezado que vaya a incluirse dos veces y es un problema porque una de las cabeceras #undef
ed una macro que se define, pero la segunda cabecera #define
d de nuevo y rompió un código y se necesita un par de horas para averiguar por qué hay definiciones contradictorias de las cosas.
No, ese es el único propósito de las protecciones incluidas, pero usarlas debería ser una obviedad: hacerlo requiere poco tiempo y potencialmente ahorra mucho.
Esa es su única razón de ser. Todavía es una buena idea, incluso si cree que tiene eso cubierto; no reduce la velocidad de tu código ni nada, y nunca está de más tener una guardia adicional.
El propósito del protector es evitar que el archivo sea re incluido en el mismo archivo .cpp más de una vez. No protege contra incluir el archivo en más de un archivo .cpp.
Si está seguro de que un archivo de encabezado no está incluido en otro archivo de encabezado, entonces no se requiere el resguardo. pero sigue siendo una buena forma.
forma aún mejor es utilizar
#pragma once
si su compilador lo soporta.
El protector de inclusión es mejor en mi humilde opinión porque es más portátil. Evito depender de características específicas del compilador como la plaga. –
@Chris: la portabilidad es importante para el código fuente abierto. Pero generalmente no es para fuente cerrada. #pragma una vez es más confiable y más rápido que los guardias porque el compilador en realidad puede 'skip_' volver a explorar el archivo. Ese es el tipo de cosas que realmente importa en una tienda de código cerrado. –
GCC en realidad optimiza la expresión de incluir guardia para hacer esencialmente lo mismo. Pero estoy de acuerdo en que, para una base de código de código cerrado con Visual Studio, '#pragma once' es bastante bueno. –
Garantizar que su código se incluye una sola vez es el único propósito de un llamado "protector de encabezado".
Esto puede ser útil como si hubiera una dependencia circular entre los archivos de encabezado, no quede atrapado en un bucle sin fin de archivos incluidos.
El escenario adicional en el que puedo pensar (y lo hicimos) es crear simulaciones de C++.
Usted explícitamente en su compilación define el valor GUARD del archivo y luego puede agregar su propia realización simulada a través de -include my_mock.h como la opción del compilador adicional (usamos g ++).
my_mock.h
#define THAT_FILE_GUARD
class ThatClass
{
void connect()
{
std::cout << "mock connect" << std::endl;
}
}
El uso de un protector de cabecera como esto acelera el proceso de compilación, imaginar tener tres archivos de origen utilizando el encabezado (menos el guardia de cabecera), que a su vez significaría que el compilador tendría que incluir la cabecera (análisis sintáctico y leer la sintaxis) varias veces.
Con un protector de encabezado, el compilador dirá '¡Ja! He visto este antes, y no voy a analizar/leer la sintaxis, lo que acelera el proceso de compilación.
Espero que esto ayude, Saludos cordiales, Tom.
- 1. ¿Cuál es eficiente usar #pragma una vez o #ifndef #endif?
- 2. ¿Por qué #ifndef y #define se usan en archivos de encabezado C++?
- 3. fileName o nombre de archivo?
- 4. En C y C++, ¿por qué cada archivo .h generalmente está rodeado por las directivas #ifndef #define #endif?
- 5. Propósito de las protecciones de encabezado
- 6. El compilador de Old C se atora en #ifndef #define
- 7. django filefield return filename filename solo en la plantilla
- 8. Pregunta rápida sobre la compilación condicional (ifndef)
- 9. Declarar vectores en un archivo de encabezado de C++
- 10. El papel de #ifdef y #ifndef
- 11. ¿Hay tokens después de #endif legal?
- 12. Directiva de preprocesador #ifndef para C/C++ código
- 13. encabezado lleno de funciones en línea, ¿puedo mover el código fuera del archivo de encabezado y todavía en línea todo?
- 14. if {} en if: endif
- 15. ffmpeg filename formato de salida
- 16. inclusión no resuelta en el encabezado java en JNI
- 17. error de definición múltiple incluyendo archivo de encabezado C++ con código en línea de varias fuentes
- 18. advertencia: tokens adicionales al final de la directiva #endif
- 19. ¿Cuál es el propósito de los valores "q" en el encabezado de solicitud "Aceptar" de HTTP?
- 20. C++ g ++ no puede encontrar el tipo de 'cadena' en el archivo de encabezado de clase
- 21. Incluyendo un archivo de encabezado de otro directorio
- 22. ¿Definir estructuras autorreferenciales en un archivo de encabezado C (.h)?
- 23. ¿Cómo se llama un único encabezado cuyo propósito es incluir otros archivos de encabezado?
- 24. ¿Deberíamos desinfectar $ _FILES ['filename'] ['name']?
- 25. ¿cómo es #if/#endif diferente que si?
- 26. usando el encabezado() para reescribir el nombre de archivo en la URL para el pdf dinámico
- 27. Mejores prácticas para el uso de archivos de encabezado de C++
- 28. Codeigniter "file_exists ($ filename)"
- 29. ¿Cuál es el propósito del archivo vshost.exe?
- 30. Proceso de suspensión iniciado con System.Diagnostic.Process.Start ("FileName")
Gracias a todos. Chris lo entiende por ser elaborado :) – deeJ
La próxima vez que necesite romper mi límite de reputación, solo recordaré publicar mientras procrastino mi tarea. :) –