Việc thực hành quan trọng ở đây là có xung quanh mỗi foo.h nộp một người bảo vệ như:
#ifndef _FOO_H
#define _FOO_H
...rest of the .h file...
#endif
Điều này ngăn cản nhiều tạp chất, với vòng lặp và tất cả những nỗi kinh hoàng như vậy. Một khi bạn đảm bảo mọi tập tin bao gồm được bảo vệ, các chi tiết cụ thể ít quan trọng hơn.
Tôi thích một nguyên tắc hướng dẫn mà Adam thể hiện: đảm bảo rằng, nếu tệp nguồn chỉ bao gồm a.h
, nó sẽ không tránh khỏi lỗi do a.h
giả định các tệp khác đã được đưa vào trước đó - ví dụ: nếu a.h
yêu cầu b.h
để được bao gồm trước đó, nó có thể và chỉ nên bao gồm b.h (các vệ sĩ sẽ làm cho rằng một noop nếu b.h là đã bao gồm trước)
Ngược lại, một file nguồn nên bao gồm các tiêu đề mà từ đó nó được đòi hỏi một cái gì đó (macro, tờ khai, vv), không cho rằng tiêu đề khác chỉ đến trong một cách kỳ diệu bởi vì nó có bao gồm một số.
Nếu bạn đang sử dụng các lớp học theo giá trị, than ôi, bạn cần tất cả các chi tiết đẫm máu của lớp học trong một số .h
bạn bao gồm. Nhưng đối với một số sử dụng thông qua tài liệu tham khảo hoặc con trỏ, chỉ cần một số class sic;
là đủ. Ví dụ, tất cả những thứ khác bằng nhau, nếu lớp a có thể lấy đi một con trỏ thành một thể hiện của lớp b (tức là một thành viên class b *my_bp;
chứ không phải là thành viên class b *my_b;
), việc ghép nối giữa các tệp có thể trở nên yếu hơn (giảm nhiều biên dịch lại)) -- ví dụ b.h
có thể có ít hơn class b;
trong khi tất cả các chi tiết đẫm máu trong b_impl.h
được bao gồm chỉ bởi các tiêu đề mà thực sự cần nó ...
Nguồn
2009-11-09 01:58:35
@mgd - Nếu tôi có tiêu đề có 10 bao gồm và nguồn có 10 bao gồm khác nhau, tôi có nên chuyển phần bao gồm từ đầu trang sang nguồn để nguồn có 20 bao gồm không? –
Xem câu trả lời hoàn chỉnh hơn của alex. Một ngoại lệ cho điều này là nếu bạn có tiêu đề được biên dịch trước, trong trường hợp đó bao gồm tất cả tiêu đề nền tảng/khung/hệ điều hành sẽ không bao giờ thay đổi thành một tệp và bao gồm ở mọi nơi –