Ao dividir seu código em vários arquivos, o que exatamente deve ir para um arquivo .h e o que deve ir para um arquivo .cpp?
c++
header-files
Enrico Tuvera Jr
fonte
fonte
.hpp
arquivo enquanto as declarações C vão para um.h
arquivo. Isso é muito útil ao misturar código C e C ++ (por exemplo, módulos legados em C).Respostas:
Os arquivos de cabeçalho (
.h
) são projetados para fornecer as informações que serão necessárias em vários arquivos. Coisas como declarações de classe, protótipos de função e enumerações geralmente vão em arquivos de cabeçalho. Em uma palavra, "definições".Os arquivos de código (
.cpp
) são projetados para fornecer as informações de implementação que só precisam ser conhecidas em um arquivo. Em geral, corpos de função e variáveis internas que devem / nunca serão acessadas por outros módulos são o que pertence aos.cpp
arquivos. Em uma palavra, "implementações".A pergunta mais simples de se fazer para determinar o que pertence onde é "se eu mudar isso, terei que mudar o código em outros arquivos para fazer as coisas compilarem novamente?" Se a resposta for "sim", provavelmente ele pertence ao arquivo de cabeçalho; se a resposta for "não", provavelmente ele pertence ao arquivo de código.
fonte
export
). A única maneira de contornar o # 1 é PIMPL. # 2 seria possível seexport
fosse suportado e pode ser possível usando c ++ 0x eextern
modelos. IMO, arquivos de cabeçalho em c ++ perdem muito de sua utilidade.O fato é que, em C ++, isso é um pouco mais complicado do que a organização de cabeçalho / origem C.
O que o compilador vê?
O compilador vê um grande arquivo de origem (.cpp) com seus cabeçalhos incluídos corretamente. O arquivo de origem é a unidade de compilação que será compilada em um arquivo de objeto.
Então, por que os cabeçalhos são necessários?
Porque uma unidade de compilação pode precisar de informações sobre uma implementação em outra unidade de compilação. Assim, pode-se escrever, por exemplo, a implementação de uma função em uma fonte, e escrever a declaração dessa função em outra fonte que precise usá-la.
Nesse caso, existem duas cópias das mesmas informações. O que é mal ...
A solução é compartilhar alguns detalhes. Embora a implementação deva permanecer na Fonte, a declaração de símbolos compartilhados, como funções, ou definição de estruturas, classes, enums, etc., pode precisar ser compartilhada.
Os cabeçalhos são usados para colocar esses detalhes compartilhados.
Mova para o cabeçalho as declarações do que precisa ser compartilhado entre várias fontes
Nada mais?
Em C ++, existem algumas outras coisas que podem ser colocadas no cabeçalho porque também precisam ser compartilhadas:
Mova para o cabeçalho TUDO o que precisa ser compartilhado, incluindo implementações compartilhadas
Isso significa que pode haver fontes dentro dos cabeçalhos?
Sim. Na verdade, existem muitas coisas diferentes que podem estar dentro de um "cabeçalho" (ou seja, compartilhado entre as fontes).
Torna-se complicado e, em alguns casos (dependências circulares entre símbolos), impossível mantê-lo em um cabeçalho.
Os cabeçalhos podem ser divididos em três partes
Isso significa que, em um caso extremo, você poderia ter:
Vamos imaginar que temos um MyObject modelado. Poderíamos ter:
.
.
.
Uau!
Na "vida real", geralmente é menos complicado. A maior parte do código terá apenas um cabeçalho / organização de origem simples, com algum código embutido no código-fonte.
Mas em outros casos (objetos modelados se conhecendo), tive que ter para cada objeto uma declaração separada e cabeçalhos de implementação, com uma fonte vazia incluindo esses cabeçalhos apenas para me ajudar a ver alguns erros de compilação.
Outra razão para dividir cabeçalhos em cabeçalhos separados pode ser acelerar a compilação, limitando a quantidade de símbolos analisados ao estritamente necessário e evitando recompilação desnecessária de uma fonte que se preocupa apenas com a declaração direta quando uma implementação de método inline é alterada.
Conclusão
Você deve tornar sua organização de código o mais simples possível e o mais modular possível. Coloque o máximo possível no arquivo de origem. Exponha apenas nos cabeçalhos o que precisa ser compartilhado.
Mas no dia em que você tiver dependências circulares entre objetos modelados, não se surpreenda se sua organização de código se tornar um pouco mais "interessante" que a organização de cabeçalho / fonte simples ...
^ _ ^
fonte
além de todas as outras respostas, direi o que você NÃO coloca em um arquivo de cabeçalho: a
using
declaração (o mais comum éusing namespace std;
) não deve aparecer em um arquivo de cabeçalho porque poluem o namespace do arquivo de origem no qual está incluída .fonte
using
para trazer coisas para um namespace global em um cabeçalho.static inline
em C99, por causa de algo a ver com o que acontece quando você combina vinculação interna com modelos. Os namespaces Anon permitem que você "oculte" funções, preservando a ligação externa.O que compila em nada (pegada binária zero) vai para o arquivo de cabeçalho.
As variáveis não compilam em nada, mas as declarações de tipo sim (porque elas apenas descrevem como as variáveis se comportam).
funções não, mas funções inline sim (ou macros), porque elas produzem código apenas quando chamadas.
os modelos não são códigos, eles são apenas uma receita para criar código. então eles também vão em arquivos h.
fonte
Em geral, você coloca declarações no arquivo de cabeçalho e definições no arquivo de implementação (.cpp). A exceção a isso são os modelos, em que a definição também deve ir no cabeçalho.
Esta pergunta e outras semelhantes a ela têm sido feitas com frequência no SO - consulte Por que os arquivos de cabeçalho e os arquivos .cpp no C ++? e Arquivos de cabeçalho C ++, separação de código, por exemplo.
fonte
Suas declarações de classe e função mais a documentação e as definições para funções / métodos embutidos (embora alguns prefiram colocá-los em arquivos .inl separados).
fonte
Principalmente o arquivo de cabeçalho contém o esqueleto da classe ou declaração (não muda com frequência)
e o arquivo cpp contém a implementação da classe (muda freqüentemente).
fonte
o arquivo de cabeçalho (.h) deve ser para declarações de classes, structs e seus métodos, protótipos, etc. A implementação desses objetos é feita em cpp.
em .h
fonte
Eu esperaria ver:
a verdadeira resposta é o que não colocar:
fonte
O cabeçalho define algo, mas não diz nada sobre a implementação. (Excluindo modelos neste "metafore".
Com isso dito, você precisa dividir as "definições" em subgrupos, existem, neste caso, dois tipos de definições.
Agora, é claro que estou falando sobre o primeiro subgrupo.
O cabeçalho existe para definir o layout de sua estrutura, a fim de ajudar o resto do software a usar a implementação. Você pode querer vê-lo como uma "abstração" de sua implementação, o que é dito com veemência, mas acho que se encaixa muito bem neste caso.
Como os cartazes anteriores disseram e mostraram, você declara áreas de uso público e privado e seus cabeçalhos, isso também inclui variáveis públicas e privadas. Agora, não quero entrar no design do código aqui, mas você pode querer considerar o que você colocou em seus cabeçalhos, já que essa é a camada entre o usuário final e a implementação.
fonte
fonte
Cabeçalho (.h)
Corpo (.cpp)
Como regra geral, você coloca a parte "compartilhada" do módulo no .h (a parte que os outros módulos precisam ser capazes de ver) e a parte "não compartilhada" no .cpp
PD: Sim, incluí variáveis globais. Eu os usei algumas vezes e é importante não defini-los nos cabeçalhos, ou você obterá muitos módulos, cada um definindo sua própria variável.
EDIT: Modificado após o comentário de David
fonte