2015-05-09 22 views
15

Tôi đọc mã nguồn dcmtk, và tìm thấy một bình luận trong ofstdinc.h:Loại tệp tiêu đề nào không được bảo vệ chống lại sự bao gồm nhiều tệp?

// this file is not and should not be protected against multiple inclusion 

Và những loại tập tin tiêu đề KHÔNG NÊN được bảo vệ chống lại nhiều bao gồm?

+1

Những người được cố gắng sử dụng một hack (bao gồm nhiều) để giải quyết một vấn đề. Trong mã mới của riêng bạn, tốt nhất là nên thử và tránh loại giải pháp đó và luôn luôn sử dụng bao gồm cả bảo vệ. – pmg

Trả lời

12

Lập trình siêu lập trình tiền xử lý. Tức là, sử dụng tệp được bao gồm như một loại hàm thời gian biên dịch thực hiện một số nhiệm vụ. Các đối số cho hàm là các macro. Ví dụ, các tập tin bạn liên kết có một phần trông như thế này:

// define INCLUDE_STACK to include "ofstack.h" 
#ifdef INCLUDE_STACK 
#include "dcmtk/ofstd/ofstack.h" 
#endif 

Vì vậy, nếu tôi muốn bao gồm "ofstack.h", tôi sẽ làm như vậy như thế này:

#define INCLUDE_STACK 
#include "ofstdinc.h" 
#undef INCLUDE_STACK 

Bây giờ, hãy tưởng tượng sau đó xuống dòng, ai đó muốn sử dụng phần đặc biệt này của tiêu đề:

// define INCLUDE_STRING to include "ofstring.h" 
#ifdef INCLUDE_STRING 
#include "dcmtk/ofstd/ofstring.h" 
#endif 

Vì vậy, họ làm như sau:

#define INCLUDE_STRING 
#include "ofstdinc.h" 
#undef INCLUDE_STRING 

Nếu "ofstdinc.h" đã bao gồm bảo vệ, nó sẽ không được bao gồm.

+0

Trong trường hợp các tiêu đề như vậy tôi đã nhìn thấy (thường được sử dụng để dán trong các cơ quan của enums như trong câu trả lời khác), '# undefs' nằm trong chính phần đầu. Do đó, không cần sao chép mã '# undef''ing ở khắp mọi nơi mà tiêu đề được sử dụng và không thể vô tình quên làm như vậy. –

0

Bạn hầu như luôn muốn bảo vệ chống lại nhiều lần đưa vào. Thời gian duy nhất bạn không muốn làm như vậy là nếu bạn đang làm một số công cụ ưa thích với các macro C và do đó bạn muốn có nhiều sự bao gồm để tạo mã mà bạn mong muốn (không có ví dụ về điều này).

+0

Bạn có thể chỉ cho tôi một ví dụ không? Cảm ơn! – sfz

12

Một ví dụ là các tệp tiêu đề mong muốn bạn xác định macro. Hãy xem xét một tiêu đề m.h với

M(foo, "foo") 
M(bar, "bar") 
M(baz, "baz") 

này có thể được sử dụng trong một số tiêu đề khác như thế này:

#ifndef OTHER_H 
#define OTHER_H 

namespace other 
{ 
    enum class my_enum 
    { 
#define M(k, v) k, 
#include "m.h" 
#undef M 
    }; 

    void register_my_enum(); 
} 

#endif 

và trong một số tập tin khác (có thể thực hiện):

#include "other.h" 

namespace other 
{ 
    template< typename E > 
    void register_enum_string(E e, const char* s) { ... } 

    void register_my_enum() 
    { 
#define M(k, v) register_enum_string(k, v); 
#include "m.h" 
#undef M 
    } 
} 
+1

FWIW, những thứ này đôi khi được gọi là [X macro] (https://en.wikipedia.org/wiki/X_Macro). –

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