Pergunta

Eu sempre usei um arquivo *.h para as minhas definições de classe, mas depois de ler algum código impulso biblioteca, percebi que todos eles *.hpp uso. Eu sempre tive uma aversão a essa extensão de arquivo, acho que principalmente porque eu não estou acostumado com isso.

Quais são as vantagens e desvantagens do uso *.hpp sobre *.h?

Foi útil?

Solução

Aqui estão algumas razões para ter diferentes nomeação de C vs cabeçalhos C ++:

  • automática de código formatação, você pode ter diferentes orientações para a formatação de código C e C ++. Se os cabeçalhos são separados por extensão, você pode definir o seu editor para aplicar o apropriado formatação automaticamente
  • Naming, eu estive em projetos onde não havia bibliotecas escritas em C e, em seguida, wrappers tinha sido implementado em C ++. Desde os cabeçalhos geralmente tinham nomes semelhantes, ou seja, Feature.h vs Feature.hpp, eles eram fáceis de distinguir.
  • Inclusão, talvez seu projeto tem versões mais apropriadas disponíveis escritos em C ++, mas você estiver usando a versão C (ver acima ponto). Se cabeçalhos são nomeados após a linguagem que eles são implementados em que você pode facilmente detectar todos os C-cabeçalhos e verificar se há versões C ++.

Lembre-se, C é não C ++ e pode ser muito perigoso para misturar e combinar a menos que você saiba o que está fazendo. Nomear suas fontes ajuda adequadamente você diga as línguas separadas.

Outras dicas

Eu uso .hpp porque eu quero que o usuário diferenciar o que cabeçalhos são cabeçalhos C ++, e quais cabeçalhos são cabeçalhos C.

Isto pode ser importante quando seu projeto está usando ambos os módulos C e C ++: Como outra pessoa explicadas antes de mim, você deve fazê-lo com muito cuidado, e seus começa por "contrato" que você oferece através da extensão

.hpp: C ++ cabeçalhos

(ou .hxx, ou .hh, ou qualquer outro)

Este cabeçalho é para C ++ única.

Se você estiver em um módulo C, nem sequer tentar incluí-lo. Você não vai gostar, porque nenhum esforço é feito para torná-lo C-friendly (muito estaria perdido, como sobrecarga de função, namespaces, etc. etc.).

.h: C / C ++ compatível ou pura C cabeçalhos

Este cabeçalho pode ser incluído por tanto uma fonte C e um C ++ fonte, direta ou indiretamente.

Pode incluído diretamente, sendo protegido pelo macro __cplusplus:

  • O que significa que, a partir de um ponto de vista ++ C, o código C-compatível será definido como extern "C".
  • Do ponto de vista C, todo o código do C estarão bem visíveis, mas o código C ++ serão ocultados (porque ele não será compilado em um compilador C).

Por exemplo:

#ifndef MY_HEADER_H
#define MY_HEADER_H

   #ifdef __cplusplus
      extern "C"
      {
   #endif

   void myCFunction() ;

   #ifdef __cplusplus
      } // extern "C"
   #endif

#endif // MY_HEADER_H

Ou poderia ser incluído indiretamente pelo cabeçalho .hpp correspondente encerrando-o com a declaração extern "C".

Por exemplo:

#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP

extern "C"
{
#include "my_header.h"
}

#endif // MY_HEADER_HPP

e

#ifndef MY_HEADER_H
#define MY_HEADER_H

void myCFunction() ;

#endif // MY_HEADER_H

Eu sempre considerado o cabeçalho .hpp para ser uma espécie de junção de arquivos .h e .cpp ... um cabeçalho que contém detalhes de implementação também.

Normalmente, quando eu vi (e uso) .hpp como uma extensão, não há nenhum arquivo .cpp correspondente. Como já foi dito, isso não é uma regra dura e rápida, apenas como eu tendem a usar arquivos .hpp.

Não importa qual a extensão que você usa. Qualquer um é OK.

Eu uso *.h para C e *.hpp para C ++.

Editar [sugestão adicionada de Dan Nissenbaum]:

Por uma convenção, arquivos .hpp são usados ??quando os protótipos são definidos no próprio cabeçalho. Tais definições em cabeçalhos são úteis em caso de modelos, uma vez que o compilador gera o código para cada tipo apenas na instanciação de modelo. Portanto, se eles não são definidos em arquivos de cabeçalho, suas definições não serão resolvidos em tempo de ligação de outras unidades de compilação. Se o seu projecto é um único projeto que faz uso pesado de modelos C ++, esta convenção pode ser útil.

Alguns bibliotecas de modelo que aderir a esta convenção fornecer cabeçalhos com extensões .hpp para indicar que eles não têm arquivos .cpp correspondente.

Algumas outras bibliotecas de modelo usar outra convenção, como usando .h para cabeçalhos C e .hpp para C ++; um bom exemplo seria a biblioteca de impulso.

Citação do impulso FAQ,

As extensões de arquivo comunicar o "tipo" do arquivo, tanto para os seres humanos e aos programas de computador. A extensão '.h' é usado para C cabeçalho arquivos e, portanto, comunica a coisa errada sobre cabeçalho C ++ arquivos. Usando nenhuma inspeção comunica extensão nada e forças do conteúdo do arquivo para determinar o tipo. Usando '.hpp' inequivocamente identifica-o como arquivo de cabeçalho C ++, e funciona bem na prática. (Rainer Deyke)

Eu recentemente comecei a usar *.hpp para cabeçalhos C ++.

A razão é que eu uso emacs como meu editor principal e entra automaticamente em c-mode quando você carrega um arquivo *.h e em c ++ - mode quando você carrega um arquivo *.hpp.

Além desse fato, não vejo boas razões para escolher *.h sobre *.hpp ou vice-versa.

Eu estou respondendo isso como um lembrete, para dar ponto ao meu comentário (s) em resposta "user1949346" a esta mesma OP.


Assim como muitos já respondeu: qualquer forma é bom. Seguido por enfatiza de suas próprias impressões.

introdutória, como também nos comentários nomeados anteriores declarou, minha opinião é extensões de cabeçalho C++ são propostos para ser .h se há realmente nenhuma razão contra ela.

Uma vez que os documentos ISO / IEC usar esta notação de arquivos de cabeçalho e nenhuma correspondência de string para .hpp mesmo ocorre em suas documentações língua sobre C++.

Mas agora estou buscando uma razão Aprovada PORQUE qualquer forma é ok, e, especialmente, porque não é assunto da língua que eu.

Então, vamos lá.

A documentação C++ (estou realmente tomando referência da versão N3690) define que um cabeçalho tem de estar de acordo com a seguinte sintaxe:

2.9 Nomes de cabeçalho

header-name:
    < h-char-sequence >
    " q-char-sequence "
h-char-sequence:
    h-char
    h-char-sequence h-char
h-char:
    any member of the source character set except new-line and >
q-char-sequence:
    q-char
    q-char-sequence q-char
q-char:
    any member of the source character set except new-line and "

Então, como podemos extrair desta parte, o nome do arquivo de cabeçalho pode ser qualquer coisa que é válido no código fonte também. Excepto contendo caracteres '\n' e dependendo se é para ser incluído por <> não é permitido conter uma >. Ou o contrário se for incluído pelo ""-incluí-lo não é permitido para conter um ".

Em outras palavras: se você tivesse um ambiente de suporte nomes de arquivos como prettyStupidIdea.>, um incluem como:

#include "prettyStupidIdea.>"

seria válida, mas:

#include <prettyStupidIdea.>>

seria inválido. A outra maneira em torno do mesmo.

E mesmo

#include <<.<>

seria um nome de arquivo de cabeçalho includable válido.

Mesmo este estaria de acordo com C++, seria uma idéia muito muito estúpido, tho.

E é por isso .hpp é válido também.

Mas não é um resultado dos comitês projetando decisões para o idioma!

Assim, discutindo sobre a utilização .hpp é o mesmo que fazê-lo sobre .cc, .mm ou que nunca mais eu li em outros posts sobre este tema.

Eu tenho que admitir que não tem nenhum indício onde .hpp veio 1 , mas eu apostaria um inventor de alguma ferramenta de análise, IDE ou algo mais preocupado com C++ veio a esta idéia para otimizar alguns internos processos ou apenas para inventar alguma (provavelmente até mesmo para eles necessariamente) novas convenções de nomenclatura.

Mas não é parte da linguagem.

E sempre que alguém decide usá-lo desta forma. Que seja porque ele gosta mais ou porque algumas aplicações do fluxo de trabalho exige, nunca 2 é uma exigência da língua. Então, quem diz que "o PP é porque ele é usado com C ++", simplesmente está errado no que diz respeito à definição idiomas.

C ++ permite que qualquer coisa respeitando o parágrafo anterior. E se há algo que o comité proposto para uso, então ele está usando .h uma vez que esta é a extensão processado em todos os exemplos do documento ISO.

Conclusão:

Enquanto você não ver / sentir qualquer necessidade de usar .h sobre .hpp ou vice-versa, você não deve se preocupar. Porque ambos seria formar um nome de cabeçalho válido da mesma qualidade em relação ao padrão. E, portanto, qualquer coisa que RODA que você use .h ou .hpp é uma restrição adicional do padrão, que poderia até mesmo ser contraditórias com outras restrições adicionais se conformam com o outro. Mas, como OP não menciona qualquer restrição idioma adicional, esta é a única resposta correta e Aprovada para a questão

" * h ou * .hpp para as suas definições de classe ." É:

Ambos são igualmente correto e aplicável desde que há restrições externas estão presentes.


1 Pelo que eu sei, aparentemente, é o quadro impulso que veio com essa extensão .hpp.

2 É claro que eu não posso dizer que algumas versões futuras trará com ele!

Eu prefiro .hpp para C ++ para torná-lo claro para ambos os editores e outros programadores que é um cabeçalho C ++ em vez de um arquivo de cabeçalho C.

C ++ ( "C Plus Plus") faz sentido como .cpp

Tendo arquivos de cabeçalho com uma extensão .hpp não tem o mesmo fluxo lógico.

Você pode chamar o seu inclui o que quiser.

Apenas necessidade de especificar que o nome completo no #include.

Eu sugiro que se você trabalhar com C para uso .h e quando com C ++ para uso .hpp.

É no final apenas uma convenção.

Codegear C ++ Builder usa .hpp para arquivos de cabeçalho automagicamente gerados a partir de arquivos de origem Delphi e .h para os seus "próprios" arquivos de cabeçalho.

Então, quando eu estou escrevendo um arquivo de cabeçalho C ++ Eu sempre uso .h.

Em um dos meus trabalhos no início dos anos 90, foi utilizado .cc e .hh para fonte e arquivos de cabeçalho, respectivamente. Eu ainda prefiro-o sobre todas as alternativas, provavelmente porque é mais fácil de digitar.

Bjarne Stroustrup e Herb Sutter tem uma declaração a esta pergunta em suas diretrizes C ++ núcleo encontrada em: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#S-source que é também referindo-se as últimas mudanças na extensão padrão (C + 11, C ++ 14, etc.)

SF.1: Use um sufixo .cpp para arquivos de código e .h para arquivos de interface se o seu projeto Y já não seguem outra convenção Razão

É uma convenção de longa data. Mas a consistência é mais importante, por isso, se seu usos projeto algo mais, siga isso. Nota

Esta convenção reflete um padrão de uso comum: cabeçalhos são mais frequentemente compartilhada com C para compilar tanto como C ++ e C, o que normalmente usa .h, e é mais fácil para citar todos os cabeçalhos .h em vez de ter diferentes extensões para apenas os cabeçalhos que se destinam a ser compartilhado com C. Por outro lado, arquivos de implementação raramente são compartilhados com C e assim deve ser tipicamente distinguidos dos arquivos .c, por isso é normalmente melhor para nomear todos C ++ implementação arquivos outra coisa (como CPP).

Os nomes específicos e.cpp não são necessários (apenas recomendado como um default) e outros nomes estão em uso generalizado. Exemplos são .hh, .C, e .cxx. Use esses nomes equivalente. Neste documento, nos referimos a e.cpp> como um atalho para arquivos de cabeçalho e implementação, mesmo que o real extensão pode ser diferente.

O IDE (se você usar um) podem ter opiniões fortes sobre suficiente.

Eu não sou um grande fã desta convenção, porque se você estiver usando uma biblioteca popular como o impulso, a sua consistência já está quebrado e você deve usar melhor .hpp.

Como muitos aqui já mencionei, eu também prefiro usar .hpp para bibliotecas só de cabeçalho que classes de modelo uso / funções. Eu prefiro usar .h para arquivos de cabeçalho acompanhados por arquivos de origem .cpp ou compartilhados ou bibliotecas estáticas.

A maioria das bibliotecas que desenvolvo são modelo baseado e, portanto, precisa ser somente cabeçalho, mas ao escrever aplicações que tendem a declaração separada da implementação e acabar com arquivos e.cpp

Felizmente, é simples.

Você deve usar a extensão .hpp se você estiver trabalhando com C ++ e você deve usar .h para C ou a mistura de C e C ++.

Eu uso .h porque é isso que os usos da Microsoft, e que seu gerador de código cria. Não há necessidade de ir contra a corrente.

Em "The C ++ Programming Language, terceira edição por Bjarne Stroustrup", o livro nº1 leitura obrigatória C ++, ele usa .h *. Então, eu assumo a melhor prática é usar .h *.

No entanto, * .hpp é muito bem também!

É fácil para ferramentas e humanos para diferenciar algo . É isso.

Na utilização convencional (por impulso, etc.), .hpp é especificamente cabeçalhos C ++. Por outro lado, é .h para não-C ++ - apenas os cabeçalhos (principalmente de C). Para detectar precisamente a linguagem do conteúdo é geralmente difícil, pois há muitos casos não-triviais, então esta diferença muitas vezes torna uma ferramenta ready-to-use fácil de escrever. Para os seres humanos, uma vez que começa a convenção, também é fácil de lembrar e fácil de usar.

No entanto, eu apontar a própria convenção nem sempre funciona, como esperado.

  • Não é forçado pela especificação de idiomas , nem C nem C ++. Existem muitos projetos que não seguem a convenção. Uma vez que você precisa para merge (misturar)-los, pode ser problemático.
  • .hpp em si não é a única opção. Por que não .hh ou .hxx? (Apesar de qualquer maneira, você geralmente precisa de pelo menos uma regra convencional sobre nomes de arquivos e caminhos.)

Eu pessoalmente uso tanto .h e .hpp em meus projetos C ++. Eu não sigo a convenção acima, porque:

  • As línguas usadas por cada parte dos projectos são explicitamente documentada. Sem chance para misturar C e C ++ no mesmo módulo (diretório). Cada biblioteca 3rdparty é necessário para conformidade com esta regra.
  • As especificações de idioma conformadas e dialetos da língua permitidos utilizados pelos projetos também são documentados. (Na verdade, eu mesmo documentar a fonte dos recursos padrão e correção de bug ( na linguagem padrão) a ser utilizado .) Isso é um pouco mais importante do que distinguir os idiomas usados ??uma vez que é demasiado propensa a erros e os custos de teste (por exemplo, compilador de compatibilidade) pode ser significativo (complicado e demorado) , especialmente em um projeto que já está em quase puro C ++. Nomes de arquivos são demasiado fracos para lidar com isso.
  • Mesmo para o mesmo dialeto C ++, pode haver mais importantes propriedades adequadas para a diferença. Por exemplo, veja a convenção abaixo.
  • Nomes de arquivos são essencialmente peças de metadados frágil. A violação da convenção não é tão fácil de detectar. Para ser estável lidar o conteúdo, uma ferramenta, eventualmente, não só deve depender de nomes. A diferença entre extensões é apenas uma dica. Ferramentas de usá-lo também não deve ser esperado se comportam mesma o tempo todo, por exemplo, de arquivos .h em github.com detectar linguagem. (Pode haver algo em comentários como shebang para esses arquivos de origem a ser melhores metadados, mas ainda não é convencional como nomes de arquivos, assim também não confiável em geral.)

I geralmente utilizar .hpp em cabeçalhos C ++ e os cabeçalhos deve ser utilizada (mantidas) em uma cabeçalho somente maneira, por exemplo como bibliotecas de modelo. Para outros cabeçalhos em .h, ou há um arquivo .cpp correspondente como aplicação, ou é um cabeçalho não-C ++. O último é trivial para diferenciar através do conteúdo do cabeçalho de seres humanos (ou por ferramentas com metadados incorporados explícito, se necessário).

A extensão do arquivo de origem pode ter significado para o seu sistema de construção, por exemplo, você pode ter uma regra em seu makefile para arquivos .cpp ou .c, ou seu compilador (por exemplo, Microsoft cl.exe) pode compilar o arquivo como C ou C ++ dependendo da extensão.

Porque você tem que fornecer todo o nome do arquivo para a directiva #include, a extensão do arquivo de cabeçalho é irrelevante. Você pode incluir um arquivo .c em outro arquivo de origem, se quiser, porque é apenas uma textuais incluem. O compilador pode ter uma opção para despejar a saída pré-processado que vai fazer isso claro (Microsoft: /P para pré-processar para o arquivo, /E para pré-processar a stdout, /EP as directivas #line omitir, /C para reter Comentários)

Você pode optar por usar .hpp para arquivos que só são relevantes para o C ++ ambiente, ou seja, eles usam recursos que não serão compiladas em C.

Não há nenhuma vantagem para qualquer extensão particular, diferente do que se pode ter um significado diferente para você, o compilador, e / ou suas ferramentas. header.h é um cabeçalho válido. header.hpp é um cabeçalho válido. header.hh é um cabeçalho válido. header.hx é um cabeçalho válido. h.header é um cabeçalho válido. this.is.not.a.valid.header é um cabeçalho válido em negação. ihjkflajfajfklaf é um cabeçalho válido. Enquanto o nome pode ser analisado corretamente pelo compilador, e o sistema de arquivos suporta, que é um cabeçalho válido, e a única vantagem de sua extensão é o que se lê nele.

Dito isto, ser capaz de fazer com precisão suposições com base na extensão é muito útil, por isso seria sábio usar um conjunto facilmente compreensível de regras para seus arquivos de cabeçalho. Pessoalmente, eu prefiro fazer algo como isto:

  1. Se já existem quaisquer orientações estabelecidas, segui-los para evitar confusão.
  2. Se todos os arquivos de origem do projeto são para a mesma linguagem, uso .h. Não há nenhuma ambiguidade.
  3. Se alguns cabeçalhos são compatíveis com vários idiomas, enquanto outros só são compatíveis com uma única língua, as extensões são baseados na linguagem mais restritiva que um cabeçalho é compatível com. Um cabeçalho compatível com C, ou com ambos C & C ++, recebe .h, enquanto um cabeçalho compatível com C ++, mas não C recebe .hpp ou .hh ou algo do tipo.

Isto, naturalmente, é apenas um dos muitos maneiras de lidar com extensões, e você não pode necessariamente confiar a sua primeira impressão, mesmo se as coisas parecem simples. Por exemplo, eu vi menção de usar .h para cabeçalhos normais, e .tpp para cabeçalhos que contêm apenas definições para funções de membro de classe de modelo, com arquivos .h que definem as classes templated incluindo os arquivos .tpp que definem as suas funções de membro (em vez dos .h cabeçalho directamente contendo tanto a declaração de função e a definição). Em outro exemplo, um bom número de pessoas sempre refletem a linguagem do cabeçalho em sua extensão, mesmo quando não há nenhuma chance de ambiguidade; a eles, .h é sempre um cabeçalho C e .hpp (ou .hh, ou .hxx, etc.) é sempre um cabeçalho de C ++. E mais uma vez, algumas pessoas usam .h para "cabeçalho associado com um arquivo de origem" e .hpp para "cabeçalho com todas as funções em linha definidos".

Considerando isso, a principal vantagem viria em forma consistente nomear seus cabeçalhos no mesmo estilo, e fazer esse estilo facilmente perceptível a qualquer um examinar seu código. Desta forma, qualquer pessoa familiarizada com o seu estilo de codificação de costume será capaz de determinar o que você quer dizer com qualquer extensão com apenas um olhar superficial.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top