FWIW, eu odeio arquivos .inl. Por que dividir seu código mais do que o necessário?
Shog9
10
@ shog9: Para separar a interface da implementação. Sempre odiei os arquivos C # e Java porque são muito difíceis de ler a interface por causa de todos os detalhes de implementação complicados.
Martin York
8
@Martin - infelizmente C ++ nos dá uma má combinação de ambos os mundos - a interface e parte da implementação no cabeçalho, o resto da implementação no arquivo .cpp. Mesmo se você evitar funções embutidas (ou colocá-las em arquivos .inl), terá que bagunçar a interface com os detalhes incômodos de membros privados, a menos que seja capaz de usar religiosamente o idioma pimpl.
Michael Burr
5
Sim, nunca entendi o argumento de que os cabeçalhos separam a interface da implementação. Eles obviamente não querem. Uma interface não deve conter todos os membros privados.
jalf
@LokiAstari: Para ser justo, Java / C # tem ferramentas muito boas, fornecendo o esboço da interface automaticamente. Pode-se dizer o contrário: em C ++, você tem que resolver manualmente um problema, que pode ser totalmente resolvido por computadores.
bluenote10,
Respostas:
139
.inlos arquivos nunca são obrigatórios e não têm nenhum significado especial para o compilador. É apenas uma forma de estruturar seu código que fornece uma dica para os humanos que podem lê-lo.
Eu uso .inlarquivos em dois casos:
Para definições de funções embutidas.
Para definições de modelos de funções.
Em ambos os casos, coloco as declarações das funções em um arquivo de cabeçalho, que é incluído por outros arquivos, e então #includeo .inlarquivo na parte inferior do arquivo de cabeçalho.
Eu gosto porque separa a interface da implementação e torna o arquivo de cabeçalho um pouco mais fácil de ler. Se você se preocupa com os detalhes da implementação, pode abrir o .inlarquivo e lê-lo. Se não, você não precisa.
Na verdade, trata-se principalmente de separar a interface da implementação.
Pavel Minaev
1
Também vi .ipp e .ixx usados para definições in-line e .tpp e .txx para o modelo um.
AProgrammer
1
Por exemplo, a GNU Standard C ++ Library usa .tccpara arquivos de implementação de modelo.
musiphil
1
@NickMeyer glmusa .hpp e .inl exatamente da mesma maneira que você mencionou acima. Bom saber, obrigado pela ótima resposta :)
legends2k
Então, é como um cabeçalho?
Aaron Franke
90
Nick Meyer está certo: o compilador não se preocupa com a extensão do arquivo que você está incluindo, então coisas como ".h", ".hpp", ".hxx", ".hh", ".inl", ".inc", etc. são uma convenção simples, para deixar claro o que os arquivos devem conter.
O melhor exemplo são os arquivos de cabeçalho STL que não possuem qualquer extensão.
Normalmente, os arquivos ".inl" contêm código embutido (daí a extensão ".inl").
Esses arquivos arquivos ".inl" são uma necessidade quando você tem um ciclo de dependência entre o código do cabeçalho .
Por exemplo:
// A.hppstruct A
{void doSomethingElse(){// Etc.}void doSomething(B & b){
b.doSomethingElse();}};
E:
// B.hppstruct B
{void doSomethingElse(){// Etc.}void doSomething(A & a){
a.doSomethingElse();}};
Não há como fazer com que seja compilado, incluindo o uso de declaração de encaminhamento.
A solução é dividir a definição e a implementação em dois tipos de arquivos de cabeçalho:
hpp para declaração / definição de cabeçalho
inl para implementação de cabeçalho
Que se divide no seguinte exemplo:
// A.hppstruct B ;struct A
{void doSomethingElse();void doSomething(B & b);};
Isso explica o real benefício (ou necessidade) da separação e deveria ter sido escolhido como a resposta.
musiphil
Se a função não fosse embutida, você padronizaria o arquivo .cpp para a parte de implementação?
Bublafus de
@Bublafus If the function were not inline, you would you standard .cpp file for the implementation part?:: Possivelmente. Os modelos são exemplos de código que geralmente não podem ser ocultados em arquivos .CPP, portanto, nesse caso, o arquivo .INL seria obrigatório.
paercebal
32
Já que ninguém mais mencionou:
O uso de arquivos .inl para armazenar suas funções embutidas pode ser útil para acelerar as compilações.
Se você incluir apenas as declarações (.h) onde precisa de declarações, e incluir apenas implementações inline (.inl) onde você precisa (ou seja, provavelmente apenas em .cpp e outros arquivos .inl, não .h's), ele pode ter um efeito benéfico em suas dependências de cabeçalho.
Isso pode ser uma vitória significativa em projetos maiores com muitas classes interagindo.
+1: o mundo é definitivamente um lugar diferente quando você gerencia milhões de linhas de código e milhares de arquivos.
gatorfax
então você nunca deve incluir .inl em arquivos de cabeçalho? Sempre tive a sensação de que .inl deve ser colocado na parte inferior dos arquivos de cabeçalho, pois as funções embutidas requerem declaração e implementação para serem alcançadas de uma só vez.
Icebone1000 de
1
Icebone1000 nem todos os módulos que incluem o cabeçalho necessariamente desejam usar as funções inline, então eles não precisam que as implementações sejam lidas, eles não precisam estar presentes se não forem usados.
Andy J Buchanan
1
Não entendo como pode ser mais rápido, já que o compilador tem que trabalhar mais para incluir e combinar as unidades de tradução.
Nikos
1
@Nikos Acho que ele quis dizer mais rápido em relação a colocar todas as funções embutidas em seus arquivos de cabeçalho.
CoffeeTableEspresso
3
Na minha experiência, os arquivos .inl são usados para definir funções embutidas. Quando eles estão em um arquivo .inl, o arquivo pode ser incluído em um cabeçalho para obter funções embutidas e em um arquivo .c para obter definições de funções regulares.
Dessa forma, a mesma fonte pode funcionar mais facilmente com compiladores que não têm suporte de função embutida, bem como compiladores que têm.
Eles geralmente são usados com código C direto, nem sempre com código C ++, pois todos os compiladores C ++ suportam funções embutidas.
Não vejo sentido em fazer isso apenas para obter suporte C. Para C, você apenas condicionalmente #define inline statice define suas funções embutidas no cabeçalho.
Pavel Minaev
Acho que isso evita que várias cópias da mesma função acabem no binário. Só estou dizendo que vi arquivos .inl usados dessa forma, não que seja a única técnica (ou mesmo a melhor).
Michael Burr
1
Acredito que seja apenas uma convenção de nomenclatura para um arquivo de "cabeçalho" que inclui código embutido. é para que os arquivos .h possam conter definições e os arquivos .inl contenham código embutido que é necessário para os modelos.
Não acredito que haja algo mais nisso do que uma convenção de nomenclatura para deixar claro o propósito do arquivo
Respostas:
.inl
os arquivos nunca são obrigatórios e não têm nenhum significado especial para o compilador. É apenas uma forma de estruturar seu código que fornece uma dica para os humanos que podem lê-lo.Eu uso
.inl
arquivos em dois casos:Em ambos os casos, coloco as declarações das funções em um arquivo de cabeçalho, que é incluído por outros arquivos, e então
#include
o.inl
arquivo na parte inferior do arquivo de cabeçalho.Eu gosto porque separa a interface da implementação e torna o arquivo de cabeçalho um pouco mais fácil de ler. Se você se preocupa com os detalhes da implementação, pode abrir o
.inl
arquivo e lê-lo. Se não, você não precisa.fonte
.tcc
para arquivos de implementação de modelo.glm
usa .hpp e .inl exatamente da mesma maneira que você mencionou acima. Bom saber, obrigado pela ótima resposta :)Nick Meyer está certo: o compilador não se preocupa com a extensão do arquivo que você está incluindo, então coisas como ".h", ".hpp", ".hxx", ".hh", ".inl", ".inc", etc. são uma convenção simples, para deixar claro o que os arquivos devem conter.
O melhor exemplo são os arquivos de cabeçalho STL que não possuem qualquer extensão.
Normalmente, os arquivos ".inl" contêm código embutido (daí a extensão ".inl").
Esses arquivos arquivos ".inl" são uma necessidade quando você tem um ciclo de dependência entre o código do cabeçalho .
Por exemplo:
E:
Não há como fazer com que seja compilado, incluindo o uso de declaração de encaminhamento.
A solução é dividir a definição e a implementação em dois tipos de arquivos de cabeçalho:
hpp
para declaração / definição de cabeçalhoinl
para implementação de cabeçalhoQue se divide no seguinte exemplo:
E:
E:
E:
Desta forma, você pode incluir qualquer arquivo ".inl" que você precisa em sua própria fonte, e ele funcionará.
Novamente, os nomes de sufixo dos arquivos incluídos não são realmente importantes, apenas seus usos.
fonte
If the function were not inline, you would you standard .cpp file for the implementation part?
:: Possivelmente. Os modelos são exemplos de código que geralmente não podem ser ocultados em arquivos .CPP, portanto, nesse caso, o arquivo .INL seria obrigatório.Já que ninguém mais mencionou:
O uso de arquivos .inl para armazenar suas funções embutidas pode ser útil para acelerar as compilações.
Se você incluir apenas as declarações (.h) onde precisa de declarações, e incluir apenas implementações inline (.inl) onde você precisa (ou seja, provavelmente apenas em .cpp e outros arquivos .inl, não .h's), ele pode ter um efeito benéfico em suas dependências de cabeçalho.
Isso pode ser uma vitória significativa em projetos maiores com muitas classes interagindo.
fonte
Na minha experiência, os arquivos .inl são usados para definir funções embutidas. Quando eles estão em um arquivo .inl, o arquivo pode ser incluído em um cabeçalho para obter funções embutidas e em um arquivo .c para obter definições de funções regulares.
Dessa forma, a mesma fonte pode funcionar mais facilmente com compiladores que não têm suporte de função embutida, bem como compiladores que têm.
Eles geralmente são usados com código C direto, nem sempre com código C ++, pois todos os compiladores C ++ suportam funções embutidas.
fonte
#define inline static
e define suas funções embutidas no cabeçalho.Acredito que seja apenas uma convenção de nomenclatura para um arquivo de "cabeçalho" que inclui código embutido. é para que os arquivos .h possam conter definições e os arquivos .inl contenham código embutido que é necessário para os modelos.
Não acredito que haja algo mais nisso do que uma convenção de nomenclatura para deixar claro o propósito do arquivo
fonte