Protetores de header em C ++

Em LearnCpp.com | 1.10 – Uma primeira olhada no pré-processador . Sob os guardas de header , há aqueles trechos de código:

add.h:

#include "mymath.h" int add(int x, int y); 

subtract.h:

 #include "mymath.h" int subtract(int x, int y); 

main.cpp:

 #include "add.h" #include "subtract.h" 

Ao implementar o protetor de header , ele é mencionado da seguinte maneira:

 #ifndef ADD_H #define ADD_H // your declarations here #endif 
  • O que a declaração poderia estar aqui? E, deve int main() vir depois #endif ?
  • Está adicionando _H uma convenção ou um deve fazer coisa?

Obrigado.

O FILENAME_H é uma convenção. Se você realmente quisesse, você poderia usar #ifndef FLUFFY_KITTENS como um protetor de header (desde que não tenha sido definido em nenhum outro lugar), mas isso seria um bug complicado se você o definisse em algum outro lugar, como o número de gatinhos para uma coisa ou outra.

No arquivo de header add.h as declarações estão literalmente entre #ifndef e #endif .

 #ifndef ADD_H #define ADD_H #include "mymath.h" int add(int x, int y); #endif 

Finalmente, int main() não deveria estar em um arquivo de header. Deve sempre estar em um arquivo .cpp .

Para esclarecer:

#ifndef ADD_H basicamente significa “se ADD_H não foi #defined no arquivo ou em um arquivo incluído, então compile o código entre as diretivas #ifndef e #endif “. Portanto, se você tentar #include "add.h" mais de uma vez em um arquivo .cpp , o compilador verá o que o ADD_H já estava #defined e ignorará o código entre #ifndef e #endif . Os protetores de header impedem que um arquivo de header seja incluído várias vezes no mesmo arquivo .cpp . Os protetores de header não impedem que outros arquivos .cpp incluam o arquivo de header. Mas todos os arquivos .cpp podem include o arquivo de header protegido apenas uma vez .

  • O resultado do pré-processamento de um arquivo de implementação (“.cpp”) é uma unidade de tradução (TU).

  • Os headers podem include outros headers, portanto, um header pode ser incluído indiretamente várias vezes dentro da mesma TU. (Seu mymath.h é um exemplo disso.)

  • As definições só podem ocorrer no máximo uma vez por TU. (Algumas definições também não devem estar em várias TUs; este caso é um pouco diferente e não é discutido aqui.)

  • O problema inclui a solução de proteção está evitando erros de múltipla definição quando um determinado header é incluído mais de uma vez em uma TU.

  • Incluir guardas de trabalho “wrapping” o conteúdo do header de tal forma que o segundo e subseqüentes inclui são não-ops. As diretivas # ifndef / # define devem ser as duas primeiras linhas do arquivo, e #endif deve ser o último.

  • Guardas de inclusão são usadas apenas nos headers. Não defina sua function principal em um header: coloque-a em um arquivo de implementação.

Se você tem um header que irá definir um tipo e declarar uma function, mas também precisa de um header em si:

 #include "other_header.h" struct Example {}; void f(); 

“Envolvendo” com guardas de inclusão dá o conteúdo completo do arquivo:

 #ifndef UNIQUE_NAME_HERE #define UNIQUE_NAME_HERE #include "other_header.h" struct Example {}; void f(); #endif 

O nome usado para o protetor de inclusão deve ser exclusivo, caso contrário, nomes conflitantes darão resultados confusos. Esses nomes são apenas macros simples e não há nada na linguagem que imponha um determinado estilo. No entanto, as convenções do projeto geralmente impõem requisitos. Existem vários estilos de nomenclatura de guarda que você pode encontrar aqui no SO e em outros lugares; Esta resposta fornece bons critérios e uma boa visão geral.

Tudo o que os protetores de header fazem é permitir que seus headers sejam incluídos apenas uma vez. (Se eles forem incluídos várias vezes, eles serão ignorados.)

O nome que você usa não importa, mas é convencional usar o nome do arquivo em maiúsculas, incluindo a extensão que você demonstrou.

Seu main deve estar em um arquivo .cpp , mas se você o colocar em um header, coloque-o dentro dos guardas para que ele não seja declarado várias vezes.

Não, o int main () entra em um .cpp. As declarações são as outras coisas que você vai colocar no header. _H é uma convenção, você pode ver várias convenções de guarda de header ao redor.

Eu declaro uma declaração no arquivo de header e definições ou int main() vem no arquivo source.cpp .

_H está lá apenas para indicar que alguém vai include arquivos de header usando guardas de inclusão.

Se você está no MSVC ++, você também pode usar #pragma once