FWIW, nienawidzę plików .inl. Po co dzielić kod bardziej niż to konieczne?
Shog9
10
@ shog9: Aby oddzielić interfejs od implementacji. Zawsze nienawidziłem plików C # i Java, ponieważ tak trudno było odczytać interfejs z powodu wszystkich bałaganu w szczegółach implementacji.
Martin York,
8
@Martin - niestety C ++ daje nam złe połączenie obu światów - interfejsu i części implementacji w nagłówku, reszta implementacji w pliku .cpp. Nawet jeśli unikasz funkcji inline (lub umieszczasz je w plikach .inl), musisz zaśmiecać interfejs brzydkimi szczegółami prywatnych członków, chyba że jesteś w stanie religijnie używać idiomu pimpl.
Michael Burr,
5
Tak, nigdy nie rozumiałem argumentu, że nagłówki oddzielają interfejs od implementacji. Oczywiście nie. Interfejs nie powinien zawierać wszystkich prywatnych członków.
jalf
@LokiAstari: Aby być uczciwym, Java / C # ma bardzo dobre narzędzia zapewniające automatyczny zarys interfejsu. Można by to ująć na odwrót: w C ++ trzeba ręcznie rozwiązać problem, który komputer może w pełni rozwiązać.
bluenote10
Odpowiedzi:
140
.inlpliki nigdy nie są obowiązkowe i nie mają specjalnego znaczenia dla kompilatora. Jest to tylko sposób na uporządkowanie kodu, który jest wskazówką dla ludzi, którzy mogą go przeczytać.
Używam .inlplików w dwóch przypadkach:
Definicje funkcji wbudowanych.
Definicje szablonów funkcji.
W obu przypadkach deklaracje funkcji umieszczam w pliku nagłówkowym, który jest dołączany do innych plików, a następnie #includeumieszczam .inlplik na dole pliku nagłówkowego.
Podoba mi się, ponieważ oddziela interfejs od implementacji i sprawia, że plik nagłówkowy jest trochę łatwiejszy do odczytania. Jeśli zależy Ci na szczegółach implementacji, możesz otworzyć .inlplik i przeczytać. Jeśli nie, nie musisz.
Rzeczywiście, chodzi głównie o oddzielenie interfejsu od implementacji.
Pavel Minaev
1
Widziałem również .ipp i .ixx używane do definicji wbudowanych oraz .tpp i .txx jako szablon pierwszy.
AProgrammer,
1
Na przykład biblioteka GNU Standard C ++ używa .tccplików implementacji szablonów.
musiphil
2
@NickMeyer glmużywa .hpp i .inl w dokładnie taki sam sposób, jak wspomniałeś powyżej. Dobrze wiedzieć, dzięki za świetną odpowiedź :)
legends2k
Więc to jest jak nagłówek?
Aaron Franke,
90
Nick Meyer ma rację: kompilator nie dba o rozszerzenie dołączanego pliku, więc takie rzeczy jak „.h”, „.hpp”, „.hxx”, „.hh”, „.inl”, „.inc” itp. są prostą konwencją, aby było jasne, co mają zawierać pliki.
Najlepszym przykładem są pliki nagłówkowe STL, które nie mają żadnego rozszerzenia.
Zwykle pliki „.inl” zawierają wbudowany kod (stąd rozszerzenie „.inl”).
Te pliki „.inl” są niezbędne, gdy istnieje cykl zależności między kodem nagłówka .
Na przykład:
// A.hppstruct A
{void doSomethingElse(){// Etc.}void doSomething(B & b){
b.doSomethingElse();}};
I:
// B.hppstruct B
{void doSomethingElse(){// Etc.}void doSomething(A & a){
a.doSomethingElse();}};
Nie ma możliwości, abyś go skompilował, w tym używając deklaracji do przodu.
Rozwiązaniem jest wtedy rozbicie definicji i implementacji na dwa rodzaje plików nagłówkowych:
hpp do deklaracji / definicji nagłówka
inl do implementacji nagłówka
Który dzieli się na następujący przykład:
// A.hppstruct B ;struct A
{void doSomethingElse();void doSomething(B & b);};
To wyjaśnia rzeczywistą korzyść (lub konieczność) separacji i powinno zostać wybrane jako odpowiedź.
musiphil
1
Gdyby funkcja nie była wbudowana, czy użyłbyś standardowego pliku .cpp dla części implementacyjnej?
Bublafus,
1
@Bublafus If the function were not inline, you would you standard .cpp file for the implementation part?:: Możliwe. Szablony to przykłady kodu, którego zwykle nie można ukryć w plikach .CPP, więc w takim przypadku plik .INL byłby obowiązkowy.
paercebal
32
Ponieważ nikt inny o tym nie wspomniał:
Użycie plików .inl do przechowywania funkcji wbudowanych może być przydatne do przyspieszenia kompilacji.
Jeśli dołączysz tylko deklaracje (.h) tam, gdzie potrzebujesz deklaracji, i włączysz tylko implementacje wbudowane (.inl) tam, gdzie ich potrzebujesz (tj. Prawdopodobnie tylko w .cpp i innych plikach .inl, a nie .h), może mieć korzystny wpływ na zależności nagłówka.
Może to być znacząca wygrana w przypadku większych projektów z wieloma interaktywnymi klasami.
+1: świat jest zdecydowanie innym miejscem, gdy zarządzasz milionami linii kodu i tysiącami plików.
gatorfax
więc nigdy nie powinieneś dołączać .inl do plików nagłówkowych? Zawsze miałem wrażenie, że .inl powinien być umieszczony na dole plików nagłówkowych, ponieważ funkcje wbudowane wymagają, aby deklaracja i implementacja były osiągalne jednocześnie.
Icebone1000
1
Icebone1000 nie wszystkie moduły, które zawierają nagłówek, muszą koniecznie używać funkcji wbudowanych, więc nie mają potrzeby wczytywania implementacji, nie muszą być obecne, jeśli nie są używane.
Andy J Buchanan
1
Nie rozumiem, jak to może być szybsze, ponieważ kompilator musi wykonać więcej pracy, aby uwzględnić i połączyć jednostki tłumaczeniowe.
Nikos,
1
@Nikos Myślę, że miał na myśli szybsze w stosunku do umieszczania wszystkich funkcji wbudowanych w plikach nagłówkowych.
CoffeeTableEspresso
3
Z mojego doświadczenia wynika, że pliki .inl służą do definiowania funkcji wbudowanych. Gdy znajdują się w pliku .inl, plik można dołączyć do nagłówka, aby uzyskać funkcje wbudowane, oraz do pliku .c, aby uzyskać zwykłe definicje funkcji.
W ten sposób to samo źródło może łatwiej współpracować z kompilatorami, które nie mają obsługi funkcji wbudowanych, jak również kompilatorami, które to robią.
Zwykle są używane z prostym kodem C, nie często z kodem C ++, ponieważ wszystkie kompilatory C ++ obsługują funkcje wbudowane.
Nie widzę sensu robienia tego tylko po to, aby uzyskać wsparcie C. W przypadku C wystarczyłoby tylko warunkowo #define inline statici zdefiniować funkcje wbudowane w nagłówku.
Pavel Minaev
Wydaje mi się, że pozwala to uniknąć umieszczenia wielu kopii tej samej funkcji w pliku binarnym. Mówię tylko, że widziałem pliki .inl używane w ten sposób, nie że to jedyna technika (lub nawet najlepsza).
Michael Burr
1
Uważam, że jest to po prostu konwencja nazewnictwa dla pliku „nagłówkowego” zawierającego kod wbudowany. jest tak, że pliki .h mogą zawierać definicje, a pliki .inl zawierają wbudowany kod, który jest niezbędny dla szablonów.
Nie wierzę, że jest w tym coś więcej niż konwencja nazewnictwa, aby wyjaśnić cel pliku
Odpowiedzi:
.inl
pliki nigdy nie są obowiązkowe i nie mają specjalnego znaczenia dla kompilatora. Jest to tylko sposób na uporządkowanie kodu, który jest wskazówką dla ludzi, którzy mogą go przeczytać.Używam
.inl
plików w dwóch przypadkach:W obu przypadkach deklaracje funkcji umieszczam w pliku nagłówkowym, który jest dołączany do innych plików, a następnie
#include
umieszczam.inl
plik na dole pliku nagłówkowego.Podoba mi się, ponieważ oddziela interfejs od implementacji i sprawia, że plik nagłówkowy jest trochę łatwiejszy do odczytania. Jeśli zależy Ci na szczegółach implementacji, możesz otworzyć
.inl
plik i przeczytać. Jeśli nie, nie musisz.źródło
.tcc
plików implementacji szablonów.glm
używa .hpp i .inl w dokładnie taki sam sposób, jak wspomniałeś powyżej. Dobrze wiedzieć, dzięki za świetną odpowiedź :)Nick Meyer ma rację: kompilator nie dba o rozszerzenie dołączanego pliku, więc takie rzeczy jak „.h”, „.hpp”, „.hxx”, „.hh”, „.inl”, „.inc” itp. są prostą konwencją, aby było jasne, co mają zawierać pliki.
Najlepszym przykładem są pliki nagłówkowe STL, które nie mają żadnego rozszerzenia.
Zwykle pliki „.inl” zawierają wbudowany kod (stąd rozszerzenie „.inl”).
Te pliki „.inl” są niezbędne, gdy istnieje cykl zależności między kodem nagłówka .
Na przykład:
I:
Nie ma możliwości, abyś go skompilował, w tym używając deklaracji do przodu.
Rozwiązaniem jest wtedy rozbicie definicji i implementacji na dwa rodzaje plików nagłówkowych:
hpp
do deklaracji / definicji nagłówkainl
do implementacji nagłówkaKtóry dzieli się na następujący przykład:
I:
I:
I:
W ten sposób możesz dołączyć dowolny plik „.inl” do swojego własnego źródła i będzie działać.
Ponownie, nazwy sufiksów dołączonych plików nie są tak naprawdę ważne, tylko ich zastosowania.
źródło
If the function were not inline, you would you standard .cpp file for the implementation part?
:: Możliwe. Szablony to przykłady kodu, którego zwykle nie można ukryć w plikach .CPP, więc w takim przypadku plik .INL byłby obowiązkowy.Ponieważ nikt inny o tym nie wspomniał:
Użycie plików .inl do przechowywania funkcji wbudowanych może być przydatne do przyspieszenia kompilacji.
Jeśli dołączysz tylko deklaracje (.h) tam, gdzie potrzebujesz deklaracji, i włączysz tylko implementacje wbudowane (.inl) tam, gdzie ich potrzebujesz (tj. Prawdopodobnie tylko w .cpp i innych plikach .inl, a nie .h), może mieć korzystny wpływ na zależności nagłówka.
Może to być znacząca wygrana w przypadku większych projektów z wieloma interaktywnymi klasami.
źródło
Z mojego doświadczenia wynika, że pliki .inl służą do definiowania funkcji wbudowanych. Gdy znajdują się w pliku .inl, plik można dołączyć do nagłówka, aby uzyskać funkcje wbudowane, oraz do pliku .c, aby uzyskać zwykłe definicje funkcji.
W ten sposób to samo źródło może łatwiej współpracować z kompilatorami, które nie mają obsługi funkcji wbudowanych, jak również kompilatorami, które to robią.
Zwykle są używane z prostym kodem C, nie często z kodem C ++, ponieważ wszystkie kompilatory C ++ obsługują funkcje wbudowane.
źródło
#define inline static
i zdefiniować funkcje wbudowane w nagłówku.Uważam, że jest to po prostu konwencja nazewnictwa dla pliku „nagłówkowego” zawierającego kod wbudowany. jest tak, że pliki .h mogą zawierać definicje, a pliki .inl zawierają wbudowany kod, który jest niezbędny dla szablonów.
Nie wierzę, że jest w tym coś więcej niż konwencja nazewnictwa, aby wyjaśnić cel pliku
źródło