2010-02-08 23 views
27

Tôi muốn đóng gói thư viện mà tôi đang làm trên thư viện chỉ dành cho tiêu đề để giúp khách hàng dễ sử dụng hơn. (Nó nhỏ và thực sự không có lý do gì để đưa nó vào một đơn vị dịch riêng biệt) Tuy nhiên, tôi không thể đặt mã của mình vào các tiêu đề vì điều này vi phạm quy tắc định nghĩa một của C++. (Giả sử rằng các tiêu đề thư viện được bao gồm trong nhiều đơn vị dịch của một dự án khách hàng)Làm cách nào để tạo thư viện chỉ dành cho tiêu đề?

Làm sao người ta sửa đổi một thư viện để làm cho nó tiêu đề chỉ?

Trả lời

45

Bạn có thể sử dụng từ khóa inline:

// header.hpp (included into multiple translation units) 

void foo_bad() {} // multiple definitions, one in every translation unit :(

inline void foo_good() {} // ok :) 

inline cho phép các mối liên kết chỉ đơn giản là chọn một định nghĩa và loại bỏ phần còn lại.

(Như vậy, nếu những định nghĩa không thực sự phù hợp, bạn sẽ có được một liều thuốc tốt của hành vi undefined ...!)


Là một sang một bên, hàm thành viên được định nghĩa trong một lớp học kiểu, đang ngầm đánh dấu inline:

struct myclass 
{ 
    void i_am_inline_implicitly() 
    { 
     // because my definition is here 
    } 

    void but_i_am_not(); 
    void neither_am_i(); 
}; 

inline void myclass::but_i_am_not() 
{ 
    // but that doesn't mean my definition cannot be explicitly inline 
} 

void myclass::neither_am_i() 
{ 
    // but in this case, no inline for me :(
} 
+4

+1 từ tôi. Điều này là khá nhiều tất cả các phương tiện nội tuyến để trình biên dịch hiện đại. –

+0

Nitpick: Nó không cho phép phá vỡ ODR; nó cho phép hàm được xác định nhiều lần. Các định nghĩa vẫn phải khớp. –

+0

@BillyONeal: Một nitpick tốt. Đã chỉnh sửa. – GManNickG

1

bảo vệ Sử dụng tiêu đề cho các bộ phận biên dịch ở một nơi.

+4

Vệ sĩ tiêu đề chỉ hoạt động trên một đơn vị dịch thuật. – GManNickG

+0

@GMan: Bạn cần gì hơn? –

+8

Tôi cũng không biết về bạn; nhưng các dự án của tôi bao gồm nhiều hơn một tệp. – GManNickG

6

bảo vệ Sử dụng tiêu đề như Liz gợi ý và đừng quên đặt "inline" trước khi phương pháp chức năng của bạn.

tức

#ifndef MY_HEADER_H_ 
#define MY_HEADER_H_ 

inline RetType FunctionName(ParamType1 param1, ParamType2 param2) 
{ 
    // Function body 
    return retType; 
} 

#endif 
+0

Nitpick: Trong C++, không có thứ gì như một phương thức. Có chức năng thành viên và chức năng không phải là thành viên. –

+1

@BillyONeal Điều đó không đúng; như bạn có thể đọc trong Stroustrups "Ngôn ngữ lập trình C++" trên trang 587, các hàm thành viên ảo là "đôi khi được gọi là các phương thức". –

4

Ngoài ra, tôi nghĩ rằng bạn sẽ cần phải tránh bất kỳ sử dụng các biến toàn cục hoặc các biến tĩnh trong mã tiêu đề chỉ-thư viện của bạn.

Các vấn đề liên quan