Lợi ích của việc khai báo trong tệp .inl là gì? Khi nào tôi cần sử dụng cùng một?
Lợi ích của việc khai báo trong tệp .inl là gì? Khi nào tôi cần sử dụng cùng một?
Câu trả lời:
.inlcác tệp không bao giờ là bắt buộc và không có ý nghĩa đặc biệt đối với trình biên dịch. Nó chỉ là một cách cấu trúc mã của bạn cung cấp một gợi ý cho những người có thể đọc nó.
Tôi sử dụng .inltệp trong hai trường hợp:
Trong cả hai trường hợp, tôi đặt các khai báo của các hàm trong một tệp tiêu đề, tệp này được bao gồm bởi các tệp khác, sau đó tôi #includeđặt .inltệp ở cuối tệp tiêu đề.
Tôi thích nó vì nó tách giao diện khỏi việc triển khai và làm cho tệp tiêu đề dễ đọc hơn một chút. Nếu bạn quan tâm đến chi tiết triển khai, bạn có thể mở .inltệp và đọc. Nếu bạn không, bạn không cần phải làm thế.
.tcccho các tệp triển khai mẫu.
glmsử dụng .hpp và .inl theo đúng như cách bạn đã đề cập ở trên.
Nick Meyer đúng: Trình biên dịch không quan tâm đến phần mở rộng của tệp bạn đang đưa vào, vì vậy những thứ như ".h", ".hpp", ".hxx", ".hh", ".inl", ".inc", v.v. là một quy ước đơn giản, để làm rõ những gì các tệp được cho là chứa.
Ví dụ tốt nhất là các tệp tiêu đề STL không có phần mở rộng nào.
Thông thường, các tệp ".inl" chứa mã nội tuyến (do đó có phần mở rộng ".inl").
Các tệp ".inl" là một tệp cần thiết khi bạn có một chu kỳ phụ thuộc giữa mã tiêu đề .
Ví dụ:
// A.hpp
struct A
{
void doSomethingElse()
{
// Etc.
}
void doSomething(B & b)
{
b.doSomethingElse() ;
}
} ;
Và:
// B.hpp
struct B
{
void doSomethingElse()
{
// Etc.
}
void doSomething(A & a)
{
a.doSomethingElse() ;
}
} ;
Không có cách nào bạn sẽ phải biên dịch nó, bao gồm cả việc sử dụng khai báo chuyển tiếp.
Giải pháp sau đó là chia nhỏ định nghĩa và triển khai thành hai loại tệp tiêu đề:
hpp để khai báo / định nghĩa tiêu đềinl để triển khai tiêu đềĐiều này được chia thành ví dụ sau:
// A.hpp
struct B ;
struct A
{
void doSomethingElse() ;
void doSomething(B & b) ;
} ;
Và:
// A.inl
#include <A.hpp>
#include <B.hpp>
inline void A::doSomethingElse()
{
// Etc.
}
inline void A::doSomething(B & b)
{
b.doSomethingElse() ;
}
Và:
// B.hpp
struct A ;
struct B
{
void doSomethingElse() ;
void doSomething(A & a) ;
} ;
Và:
// B.INL
#include <B.hpp>
#include <A.hpp>
inline void B::doSomethingElse()
{
// Etc.
}
inline void B::doSomething(A & a)
{
a.doSomethingElse() ;
}
Bằng cách này, bạn có thể đưa bất kỳ tệp ".inl" nào bạn cần vào nguồn của riêng mình và nó sẽ hoạt động.
Một lần nữa, tên hậu tố của các tệp được bao gồm không thực sự quan trọng, chỉ là công dụng của chúng.
If the function were not inline, you would you standard .cpp file for the implementation part?:: Có thể. Mẫu là ví dụ về mã thường không thể ẩn trong tệp .CPP, vì vậy trong trường hợp đó, tệp .INL sẽ là bắt buộc.
Vì không ai khác đã đề cập đến nó:
Việc sử dụng tệp .inl để lưu trữ các hàm nội tuyến của bạn có thể hữu ích để tăng tốc độ biên dịch.
Nếu bạn chỉ bao gồm các khai báo (.h) nơi bạn cần khai báo và chỉ bao gồm các triển khai nội tuyến (.inl) khi bạn cần chúng (nghĩa là có thể chỉ trong .cpp và các tệp .inl khác, không phải .h), nó có thể có ảnh hưởng có lợi đến phần phụ thuộc tiêu đề của bạn.
Đây có thể là một chiến thắng đáng kể đối với các dự án lớn hơn với nhiều lớp tương tác.
Theo kinh nghiệm của tôi, các tệp .inl được sử dụng để xác định các hàm nội tuyến. Khi chúng nằm trong tệp .inl, tệp có thể được đưa vào tiêu đề để nhận các hàm nội tuyến và trong tệp .c để nhận các định nghĩa hàm thông thường.
Bằng cách này, cùng một nguồn có thể dễ dàng làm việc hơn với các trình biên dịch không có hỗ trợ chức năng nội tuyến cũng như các trình biên dịch có hỗ trợ.
Chúng thường được sử dụng với mã C thẳng, không thường xuyên với mã C ++ vì tất cả các trình biên dịch C ++ đều hỗ trợ các hàm nội tuyến.
#define inline staticvà xác định các hàm nội tuyến của bạn trong tiêu đề.