Signifikansi file .inl di C ++


108

Apa keuntungan memiliki deklarasi dalam file .inl? Kapan saya perlu menggunakan yang sama?


3
FWIW, saya benci file .inl. Mengapa membagi kode Anda lebih dari yang diperlukan?
Shog9

10
@ shog9: Untuk memisahkan antarmuka dari implementasi. Saya selalu membenci C # dan file Java karena sangat sulit untuk membaca antarmuka karena semua detail implementasi yang berantakan.
Martin York

8
@Martin - sayangnya C ++ memberi kita kombinasi yang buruk dari kedua dunia - antarmuka dan bagian dari implementasi di header, sisanya dari implementasi di file .cpp. Meskipun Anda menghindari fungsi sebaris (atau memasukkannya ke dalam file .inl), Anda harus mengacaukan antarmuka dengan detail anggota pribadi yang mengganggu kecuali Anda dapat menggunakan idiom pimpl secara religius.
Michael Burr

5
Ya, saya tidak pernah mengerti argumen yang memisahkan antarmuka dari implementasi. Jelas tidak. Antarmuka tidak boleh berisi semua anggota pribadi.
jalf

@LokiAstari: Agar adil, Java / C # memiliki perkakas yang sangat baik yang menyediakan garis antarmuka secara otomatis. Orang mungkin akan mengatakannya sebaliknya: Dalam C ++ Anda harus menyelesaikan masalah secara manual, yang dapat diselesaikan sepenuhnya oleh komputer.
bluenote10

Jawaban:


139

.inlfile tidak pernah wajib dan tidak memiliki arti khusus bagi kompiler. Itu hanya cara menyusun kode Anda yang memberikan petunjuk kepada manusia yang mungkin membacanya.

Saya menggunakan .inlfile dalam dua kasus:

  • Untuk definisi fungsi sebaris.
  • Untuk definisi template fungsi.

Dalam kedua kasus, saya menempatkan deklarasi fungsi dalam file header, yang termasuk oleh file lain, maka saya #includeyang .inlfile pada bagian bawah file header.

Saya suka karena ini memisahkan antarmuka dari implementasi dan membuat file header sedikit lebih mudah dibaca. Jika Anda peduli dengan detail implementasi, Anda dapat membuka .inlfile dan membacanya. Jika tidak, Anda tidak perlu melakukannya.


2
Memang, ini sebagian besar tentang memisahkan antarmuka dari implementasi.
Pavel Minaev

1
Saya juga melihat .ipp dan .ixx digunakan untuk definisi inline dan .tpp dan .txx untuk template satu.
Pemrogram

1
Misalnya, Perpustakaan GNU Standard C ++ digunakan .tccuntuk file implementasi template.
musiphil

1
@NickMeyer glmmenggunakan .hpp dan .inl dengan cara yang persis sama seperti yang Anda sebutkan di atas. Senang mengetahui, terima kasih atas jawaban yang bagus :)
legends2k

Jadi, apakah ini seperti tajuk?
Aaron Franke

90

Nick Meyer benar: Kompilator tidak peduli dengan ekstensi file yang Anda masukkan, jadi hal-hal seperti ".h", ".hpp", ".hxx", ".hh", ".inl", ".inc", dll. adalah konvensi sederhana, untuk memperjelas isi file apa saja.

Contoh terbaik adalah file header STL yang tidak memiliki ekstensi apa pun.

Biasanya, file ".inl" memang berisi kode inline (karenanya ekstensi ".inl").

File-file ".inl" tersebut diperlukan ketika Anda memiliki siklus ketergantungan antara kode header .

Sebagai contoh:

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

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

Dan:

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

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

Tidak mungkin Anda membuatnya dikompilasi, termasuk menggunakan deklarasi maju.

Solusinya kemudian memecah definisi dan implementasi menjadi dua jenis file header:

  • hpp untuk deklarasi / definisi header
  • inl untuk implementasi header

Yang terurai menjadi contoh berikut:

// A.hpp

struct B ;

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

Dan:

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

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

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

Dan:

// B.hpp

struct A ;

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

Dan:

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

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

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

Dengan cara ini, Anda dapat menyertakan file ".inl" apa pun yang Anda perlukan di sumber Anda sendiri, dan ini akan berhasil.

Sekali lagi, nama sufiks dari file yang disertakan tidak terlalu penting, hanya kegunaannya.


5
Ini menjelaskan manfaat nyata (atau kebutuhan) pemisahan, dan seharusnya dipilih sebagai jawabannya.
musiphil

Jika fungsinya tidak sebaris, Anda akan menggunakan file .cpp standar untuk bagian implementasi?
Bublafus

@Bublafus If the function were not inline, you would you standard .cpp file for the implementation part?:: Mungkin. Template adalah contoh kode yang biasanya tidak dapat disembunyikan dalam file .CPP, jadi dalam hal ini, file .INL akan menjadi wajib.
paercebal

32

Karena tidak ada orang lain yang menyebutkannya:

Penggunaan file .inl untuk menyimpan fungsi inline Anda dapat berguna untuk mempercepat kompilasi.

Jika Anda hanya menyertakan deklarasi (.h) di mana Anda memerlukan deklarasi, dan hanya menyertakan implementasi inline (.inl) di mana Anda membutuhkannya (misalnya, mungkin hanya dalam .cpp dan file .inl lainnya, bukan .h), ia dapat memiliki a efek menguntungkan pada dependensi header Anda.

Ini bisa menjadi kemenangan signifikan pada proyek yang lebih besar dengan banyak kelas yang berinteraksi.


7
+1: dunia jelas merupakan tempat yang berbeda saat Anda mengelola jutaan baris kode dan ribuan file.
gatorfax

jadi Anda tidak boleh menyertakan .inl di file header? Saya selalu merasa bahwa .inl harus diletakkan di bagian bawah file header karena fungsi inline memerlukan deklarasi dan implementasi agar dapat dijangkau sekaligus.
Icebone1000

1
Icebone1000 tidak semua modul yang menyertakan tajuk ingin menggunakan fungsi sebaris, jadi mereka tidak memerlukan implementasi untuk dibaca, mereka tidak diharuskan ada jika tidak digunakan.
Andy J Buchanan

1
Saya tidak mengerti bagaimana bisa lebih cepat, karena kompilator harus melakukan lebih banyak pekerjaan untuk memasukkan dan menggabungkan unit terjemahan.
Nikos

1
@Nikos Saya pikir maksudnya lebih cepat daripada meletakkan semua fungsi inline Anda di file header Anda.
CoffeeTableEspresso

3

Dalam pengalaman saya, file .inl digunakan untuk mendefinisikan fungsi inline. Saat mereka berada dalam file .inl, file tersebut dapat dimasukkan dalam header untuk mendapatkan fungsi inline dan dalam file .c untuk mendapatkan definisi fungsi biasa.

Dengan cara ini, sumber yang sama bisa lebih mudah bekerja dengan kompiler yang tidak memiliki dukungan fungsi sebaris seperti halnya kompiler yang memilikinya.

Mereka biasanya digunakan dengan kode C langsung, tidak sering dengan kode C ++ karena semua kompiler C ++ mendukung fungsi inline.


Saya tidak melihat gunanya melakukan ini hanya untuk mendapatkan dukungan C. Untuk C, Anda cukup bersyarat #define inline static, dan menentukan fungsi inline Anda di header.
Pavel Minaev

Saya kira ini menghindari banyak salinan dari fungsi yang sama berakhir di biner. Saya hanya mengatakan saya telah melihat file .inl digunakan dengan cara ini, bukan itu satu-satunya teknik (atau bahkan yang terbaik).
Michael Burr

1

Saya percaya itu hanya konvensi penamaan untuk file "header" yang menyertakan kode inline. itu agar file .h dapat berisi definisi dan file .inl berisi kode inline yang diperlukan untuk template.

Saya tidak percaya ada yang lebih dari itu selain konvensi penamaan untuk membuat tujuan file menjadi jelas

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.