C ++ 'da bir .inl dosyasının önemi


108

Bir .inl dosyasında bildirimlere sahip olmanın avantajları nelerdir? Aynısını ne zaman kullanmam gerekir?


3
FWIW, .inl dosyalarından nefret ediyorum. Neden kodunuzu gerekenden daha fazla bölmelisiniz?
Shog9

10
@ shog9: Arayüzü uygulamadan ayırmak için. Her zaman C # ve Java dosyalarından nefret ettim çünkü tüm karmaşık uygulama ayrıntıları nedeniyle arayüzü okumak çok zor.
Martin York

8
@Martin - ne yazık ki C ++ bize her iki dünyanın da kötü bir kombinasyonunu veriyor - arayüz ve uygulamanın bir parçası başlıkta, uygulamanın geri kalanı .cpp dosyasında. Satır içi işlevlerden kaçınsanız (veya bunları .inl dosyalarına koysanız) bile, pimpl deyimini dini olarak kullanamadığınız sürece, özel üyelerin sinir bozucu ayrıntılarıyla arayüzü karıştırmanız gerekir.
Michael Burr

5
Evet, başlıkların arayüzü uygulamadan ayırdığı argümanını hiç anlamadım. Belli ki yok. Bir arayüz, tüm özel üyeleri içermemelidir.
jalf

@LokiAstari: Adil olmak gerekirse, Java / C # arayüz taslağını otomatik olarak sağlayan çok iyi araçlara sahiptir. Biri başka bir şekilde ifade edebilir: C ++ 'da, bilgisayarlar tarafından tamamen çözülebilen bir sorunu manuel olarak çözmeniz gerekir.
bluenote10

Yanıtlar:


140

.inldosyalar asla zorunlu değildir ve derleyici için özel bir önemi yoktur. Bu, kodu okuyabilecek insanlara bir ipucu sağlayan kodunuzu yapılandırmanın bir yolu.

Kullandığım .inliki durumda dosyaları:

  • Satır içi fonksiyonların tanımları için.
  • İşlev şablonlarının tanımları için.

Her iki durumda da, ben, diğer dosyaları tarafından eklenen üstbilgi dosyasında sonra fonksiyonların beyanlarını koymak başlık dosyasına altındaki dosyayı.#include.inl

Arayüzü uygulamadan ayırdığı ve başlık dosyasının okunmasını biraz daha kolaylaştırdığı için beğendim. Uygulama detaylarını önemsiyorsanız, .inldosyayı açıp okuyabilirsiniz. Eğer yapmazsan, zorunda değilsin.


2
Aslında, esas olarak arayüzü uygulamadan ayırmakla ilgilidir.
Pavel Minaev

1
Satır içi tanımlamalar için .ipp ve .ixx'in ve birinci şablon için .tpp ve .txx'in kullanıldığını da gördüm.
AProgrammer

1
Örneğin, GNU Standart C ++ Kitaplığı .tccşablon uygulama dosyaları için kullanır .
musiphil

2
@NickMeyer glm, .hpp ve .inl'yi tam olarak yukarıda bahsettiğiniz şekilde kullanır. Bilmekte
fayda var

Yani başlık gibi mi?
Aaron Franke

90

Nick Meyer haklı: Derleyici, dahil ettiğiniz dosyanın uzantısını önemsemiyor, bu nedenle ".h", ".hpp", ".hxx", ".hh", ".inl" gibi şeyler, ".inc" vb. dosyaların ne içermesi gerektiğini açıklığa kavuşturmak için basit bir kuraldır.

En iyi örnek, uzantısı olmayan STL başlık dosyalarıdır.

Genellikle, ".inl" dosyaları satır içi kod içerir (dolayısıyla ".inl" uzantısı).

Bu dosyalar ".inl" dosyaları, başlık kodu arasında bir bağımlılık döngüsüne sahip olduğunuzda bir gerekliliktir .

Örneğin:

// A.hpp
struct A
{
    void doSomethingElse()
    {
       // Etc.
    }

    void doSomething(B & b)
    {
       b.doSomethingElse() ;
    }
} ;

Ve:

// B.hpp
struct B
{
    void doSomethingElse()
    {
       // Etc.
    }

    void doSomething(A & a)
    {
       a.doSomethingElse() ;
    }
} ;

İleriye dönük bildirimi kullanmak dahil, derlemenizin hiçbir yolu yoktur.

Çözüm daha sonra tanımı ve uygulamayı iki tür başlık dosyasına bölmektir:

  • hpp başlık bildirimi / tanımı için
  • inl başlık uygulaması için

Bu, aşağıdaki örneğe ayrılıyor:

// A.hpp

struct B ;

struct A
{
    void doSomethingElse() ;
    void doSomething(B & b) ;
} ;

Ve:

// A.inl
#include <A.hpp>
#include <B.hpp>

inline void A::doSomethingElse()
{
   // Etc.
}

inline void A::doSomething(B & b)
{
   b.doSomethingElse() ;
}

Ve:

// B.hpp

struct A ;

struct B
{
    void doSomethingElse() ;
    void doSomething(A & a) ;
} ;

Ve:

// B.INL
#include <B.hpp>
#include <A.hpp>

inline void B::doSomethingElse()
{
   // Etc.
}

inline void B::doSomething(A & a)
{
   a.doSomethingElse() ;
}

Bu şekilde, ihtiyacınız olan ".inl" dosyasını kendi kaynağınıza dahil edebilirsiniz ve çalışacaktır.

Yine, dahil edilen dosyaların sonek isimleri gerçekten önemli değildir, sadece kullanımlarıdır.


5
Bu, ayrılmanın gerçek faydasını (veya gerekliliğini) açıklar ve yanıt olarak seçilmeliydi.
musiphil

1
İşlev satır içi olmasaydı, uygulama bölümü için standart .cpp dosyası olur muydunuz?
Bublafus

1
@Bublafus:: If the function were not inline, you would you standard .cpp file for the implementation part?Muhtemelen. Şablonlar, genellikle .CPP dosyalarında gizlenemeyen kod örnekleridir, bu nedenle bu durumda .INL dosyası zorunlu olacaktır.
paercebal

32

Bundan başka kimse bahsetmediğinden:

Satır içi işlevlerinizi saklamak için .inl dosyalarının kullanılması, derlemeleri hızlandırmak için yararlı olabilir.

Yalnızca bildirimlere ihtiyaç duyduğunuz bildirimleri (.h) eklerseniz ve yalnızca ihtiyaç duyduğunuz yerde satır içi uygulamaları (.inl) dahil ederseniz (yani muhtemelen yalnızca .cpp ve diğer .inl dosyalarında, .h'lerde değil), bir başlık bağımlılıklarınız üzerinde faydalı etki.

Bu, birçok etkileşimli sınıfın bulunduğu daha büyük projelerde önemli bir kazanç olabilir.


7
+1: Milyonlarca satırlık kodu ve binlerce dosyayı yönettiğinizde dünya kesinlikle farklı bir yerdir.
gatorfax

bu yüzden .inl'yi başlık dosyalarına asla eklememelisiniz? Her zaman .inl'nin başlık dosyalarının altına yerleştirilmesi gerektiği hissine kapılmıştım, çünkü satır içi işlevler bildirim ve uygulamanın aynı anda erişilebilir olmasını gerektirir.
Icebone1000

1
Icebone1000, başlığı içeren tüm modüller, satır içi işlevleri kullanmak istemeyebilir, bu nedenle uygulamaların okunmasına gerek yoktur, kullanılmadıklarında mevcut olmaları gerekmez.
Andy J Buchanan

1
Derleyicinin çeviri birimlerini dahil etmek ve birleştirmek için daha fazla iş yapması gerektiğinden, nasıl daha hızlı olabileceğini anlamıyorum.
Nikos

1
@Nikos Bence tüm satır içi işlevlerinizi başlık dosyalarınıza koymaya göre daha hızlı demek istiyordu.
CoffeeTableEspresso

3

Tecrübelerime göre, .inl dosyaları satır içi işlevleri tanımlamak için kullanılır. Bir .inl dosyasındayken, dosya, satır içi işlevleri almak için bir başlığa ve düzenli işlev tanımlarını almak için bir .c dosyasına dahil edilebilir.

Bu şekilde, aynı kaynak, satır içi işlev desteğine sahip olmayan derleyiciler ve sahip olan derleyicilerle daha kolay çalışabilir.

Tüm C ++ derleyicileri satır içi işlevleri desteklediğinden, genellikle C ++ koduyla değil, genellikle düz C koduyla kullanılırlar.


Bunu sadece C desteği almak için yapmanın anlamını görmüyorum. C için, yalnızca koşullu #define inline staticolarak ve başlıkta satır içi işlevlerinizi tanımlarsınız.
Pavel Minaev

Sanırım bu, aynı işlevin birden çok kopyasının ikili olarak sona ermesini önler. Sadece .inl dosyalarının bu şekilde kullanıldığını gördüğümü söylüyorum, bunun tek teknik (hatta en iyisi) olduğunu değil.
Michael Burr

1

Bunun yalnızca satır içi kodu içeren bir "başlık" dosyası için bir adlandırma kuralı olduğuna inanıyorum. Bu, .h dosyalarının tanımları ve .inl dosyalarının şablonlar için gerekli olan satır içi kodu içermesi içindir.

Dosyanın amacını açıklığa kavuşturmak için bir adlandırma kuralından daha fazlası olduğuna inanmıyorum

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.