ความสำคัญของไฟล์. inl ใน C ++


108

ข้อดีของการประกาศในไฟล์. inl คืออะไร? ฉันจะต้องใช้สิ่งเดียวกันนี้เมื่อใด


3
FWIW ฉันเกลียดไฟล์. inl ทำไมต้องแยกรหัสของคุณเกินความจำเป็น?
Shog9

10
@ shog9: เพื่อแยกส่วนต่อประสานจากการใช้งาน ฉันเกลียดไฟล์ C # และ Java มาตลอดเพราะมันยากที่จะอ่านอินเทอร์เฟซเนื่องจากรายละเอียดการใช้งาน messey ทั้งหมด
Martin York

8
@Martin - น่าเสียดายที่ C ++ ทำให้เรามีการผสมผสานที่ไม่ดีของทั้งสองโลก - อินเทอร์เฟซและส่วนของการใช้งานในส่วนหัวส่วนที่เหลือของการใช้งานในไฟล์. cpp แม้ว่าคุณจะหลีกเลี่ยงฟังก์ชั่นแบบอินไลน์ (หรือใส่ไว้ในไฟล์. inl) คุณต้องยุ่งกับอินเทอร์เฟซที่มีรายละเอียดที่น่ารำคาญของสมาชิกส่วนตัวเว้นแต่คุณจะสามารถใช้สำนวน pimpl ได้อย่างเคร่งครัด
ไมเคิลเบอร์

5
ใช่ฉันไม่เคยเข้าใจข้อโต้แย้งที่ว่าส่วนหัวแยกอินเทอร์เฟซออกจากการนำไปใช้งาน เห็นได้ชัดว่าพวกเขาไม่ทำ อินเทอร์เฟซไม่ควรมีสมาชิกส่วนตัวทั้งหมด
jalf

@LokiAstari: เพื่อความยุติธรรม Java / C # มีเครื่องมือที่ดีมากที่ให้โครงร่างอินเทอร์เฟซโดยอัตโนมัติ วิธีหนึ่งอาจใช้ในทางกลับกัน: ใน C ++ คุณต้องแก้ปัญหาด้วยตนเองซึ่งคอมพิวเตอร์สามารถแก้ไขได้ทั้งหมด
bluenote10

คำตอบ:


140

.inlไฟล์ไม่เคยบังคับและไม่มีความสำคัญเป็นพิเศษสำหรับคอมไพเลอร์ เป็นเพียงวิธีการจัดโครงสร้างโค้ดของคุณที่ให้คำแนะนำแก่มนุษย์ที่อาจอ่านมัน

ฉันใช้.inlไฟล์ในสองกรณี:

  • สำหรับคำจำกัดความของฟังก์ชันอินไลน์
  • สำหรับคำจำกัดความของเทมเพลตฟังก์ชัน

ในทั้งสองกรณีฉันใส่การประกาศฟังก์ชั่นในไฟล์ส่วนหัวซึ่งรวมอยู่ในไฟล์อื่นจากนั้นฉัน #include.inlไฟล์ที่ด้านล่างของไฟล์ส่วนหัว

ฉันชอบมันเพราะมันแยกอินเทอร์เฟซออกจากการใช้งานและทำให้ไฟล์ส่วนหัวอ่านง่ายขึ้นเล็กน้อย หากคุณสนใจเกี่ยวกับรายละเอียดการใช้งานคุณสามารถเปิด.inlไฟล์และอ่านได้ ถ้าไม่ทำก็ไม่ต้อง


2
อันที่จริงส่วนใหญ่เกี่ยวกับการแยกอินเทอร์เฟซออกจากการใช้งาน
Pavel Minaev

1
ฉันยังเห็น. ip และ. ixx ใช้สำหรับคำจำกัดความแบบอินไลน์และ. tpp และ. txx สำหรับเทมเพลตหนึ่ง
AProgrammer

1
ตัวอย่างเช่นไลบรารี C ++ มาตรฐาน GNU ใช้.tccสำหรับไฟล์การใช้งานเทมเพลต
musiphil

2
@NickMeyer glmใช้. hpp และ. inl ในลักษณะเดียวกับที่คุณได้กล่าวไว้ข้างต้น ขอขอบคุณสำหรับคำตอบที่ดี :)
legends2k

มันเป็นเหมือนส่วนหัวหรือไม่?
Aaron Franke

90

นิคเมเยอร์ถูกต้อง: คอมไพเลอร์ไม่สนใจส่วนขยายของไฟล์ที่คุณรวมอยู่ดังนั้นสิ่งต่างๆเช่น ".h", ".hpp", ".hxx", ".hh", ".inl", ".inc" ฯลฯ เป็นหลักการง่ายๆเพื่อให้ชัดเจนว่าไฟล์ควรมีอะไรบ้าง

ตัวอย่างที่ดีที่สุดคือไฟล์ส่วนหัว STL ซึ่งไม่มีนามสกุลใด ๆ

โดยปกติไฟล์ ".inl" จะมีโค้ดแบบอินไลน์ (ดังนั้นนามสกุล ".inl")

ไฟล์ ".inl" เหล่านั้นเป็นสิ่งจำเป็นเมื่อคุณมีวงจรการพึ่งพาระหว่างโค้ดส่วนหัว

ตัวอย่างเช่น:

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

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

และ:

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

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

ไม่มีทางที่คุณจะรวบรวมได้รวมถึงการใช้การประกาศล่วงหน้า

จากนั้นวิธีแก้ปัญหาคือการแบ่งคำจำกัดความและการใช้งานออกเป็นไฟล์ส่วนหัวสองประเภท:

  • hpp สำหรับการประกาศ / คำจำกัดความส่วนหัว
  • inl สำหรับการใช้งานส่วนหัว

ซึ่งแบ่งออกเป็นตัวอย่างต่อไปนี้:

// A.hpp

struct B ;

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

และ:

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

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

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

และ:

// B.hpp

struct A ;

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

และ:

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

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

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

ด้วยวิธีนี้คุณสามารถรวมไฟล์ ".inl" อะไรก็ได้ที่คุณต้องการในแหล่งที่มาของคุณเองและมันจะใช้งานได้

อีกครั้งชื่อต่อท้ายของไฟล์ที่รวมไม่ได้มีความสำคัญ แต่เพียงการใช้งานเท่านั้น


5
สิ่งนี้อธิบายถึงประโยชน์ที่แท้จริง (หรือความจำเป็น) ของการแยกจากกันและควรได้รับเลือกให้เป็นคำตอบ
musiphil

1
หากฟังก์ชันไม่อยู่ในบรรทัดคุณจะใช้ไฟล์. cpp มาตรฐานสำหรับส่วนการนำไปใช้งานได้หรือไม่?
Bublafus

1
@Bublafus If the function were not inline, you would you standard .cpp file for the implementation part?:: เป็นไปได้. เทมเพลตคือตัวอย่างของรหัสที่โดยปกติไม่สามารถซ่อนไว้ในไฟล์. CPP ดังนั้นในกรณีนี้ไฟล์. INL จึงเป็นสิ่งจำเป็น
paercebal

31

เนื่องจากไม่มีใครพูดถึง:

การใช้ไฟล์. inl เพื่อจัดเก็บฟังก์ชันแบบอินไลน์จะมีประโยชน์ในการเร่งความเร็วการคอมไพล์

หากคุณรวมเฉพาะการประกาศ (.h) ที่คุณต้องการการประกาศและรวมเฉพาะการใช้งานแบบอินไลน์ (.inl) ที่คุณต้องการ (เช่นอาจเป็นเฉพาะใน. cpp และไฟล์. in อื่น ๆ ไม่ใช่. h) ก็สามารถมีได้ ผลประโยชน์ต่อการพึ่งพาส่วนหัวของคุณ

นี่อาจเป็นชัยชนะครั้งสำคัญในโครงการขนาดใหญ่ที่มีคลาสโต้ตอบมากมาย


7
+1: โลกเป็นสถานที่ที่แตกต่างออกไปอย่างแน่นอนเมื่อคุณจัดการโค้ดนับล้านบรรทัดและไฟล์หลายพันไฟล์
gatorfax

ดังนั้นคุณไม่ควรรวม. inl ในไฟล์ส่วนหัว? ฉันมักจะรู้สึกว่าควรใส่. in ไว้ที่ด้านล่างของไฟล์ส่วนหัวเนื่องจากฟังก์ชันแบบอินไลน์จำเป็นต้องมีการประกาศและการนำไปใช้งานเพื่อให้เข้าถึงได้ในครั้งเดียว
Icebone1000

1
Icebone1000 ไม่ใช่โมดูลทั้งหมดที่มีส่วนหัวจำเป็นต้องใช้ฟังก์ชันอินไลน์ดังนั้นจึงไม่จำเป็นต้องอ่านการนำไปใช้งานไม่จำเป็นต้องมีอยู่หากไม่ได้ใช้
Andy J Buchanan

1
ฉันไม่เข้าใจว่ามันจะเร็วขึ้นได้อย่างไรเนื่องจากคอมไพเลอร์ต้องทำงานมากขึ้นเพื่อรวมและรวมหน่วยการแปล
Nikos

1
@Nikos ฉันคิดว่าเขาหมายถึงเร็วกว่าเมื่อเทียบกับการใส่ฟังก์ชันอินไลน์ทั้งหมดของคุณในไฟล์ส่วนหัวของคุณ
CoffeeTableEspresso

3

จากประสบการณ์ของฉันไฟล์. inl ถูกใช้เพื่อกำหนดฟังก์ชันแบบอินไลน์ เมื่ออยู่ในไฟล์. inl ไฟล์สามารถรวมอยู่ในส่วนหัวเพื่อรับฟังก์ชันแบบอินไลน์และในไฟล์. c เพื่อรับข้อกำหนดฟังก์ชันปกติ

ด้วยวิธีนี้แหล่งที่มาเดียวกันสามารถทำงานร่วมกับคอมไพเลอร์ที่ไม่มีการสนับสนุนฟังก์ชันอินไลน์ได้ง่ายขึ้นเช่นเดียวกับคอมไพเลอร์ที่ทำ

โดยปกติจะใช้กับรหัส C ตรงไม่ใช่รหัส C ++ บ่อยนักเนื่องจากคอมไพเลอร์ C ++ ทั้งหมดรองรับฟังก์ชันแบบอินไลน์


ฉันไม่เห็นประเด็นในการทำเช่นนี้เพื่อรับการสนับสนุน C สำหรับ C คุณเพียงแค่กำหนดเงื่อนไข#define inline staticและกำหนดฟังก์ชันอินไลน์ของคุณในส่วนหัว
Pavel Minaev

ฉันเดาว่าสิ่งนี้จะหลีกเลี่ยงการทำสำเนาหลาย ๆ ชุดของฟังก์ชันเดียวกันไม่ให้ลงท้ายด้วยเลขฐานสอง ฉันแค่บอกว่าฉันเคยเห็นไฟล์. inl ใช้วิธีนี้ไม่ใช่ว่าเป็นเทคนิคเดียว (หรือดีที่สุด)
Michael Burr

1

ฉันเชื่อว่ามันเป็นเพียงหลักการตั้งชื่อสำหรับไฟล์ "ส่วนหัว" ที่มีโค้ดอินไลน์ ดังนั้นไฟล์. h จึงมีคำจำกัดความและไฟล์. inl มีโค้ดอินไลน์ซึ่งจำเป็นสำหรับเทมเพลต

ฉันไม่เชื่อว่าจะมีอะไรมากกว่าการตั้งชื่อเพื่อให้จุดประสงค์ของไฟล์ชัดเจน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.