Đây là một trong những loại "nên" chứ không phải "sẽ" các loại tiêu chuẩn mã hóa. Lý do là bạn sẽ phải viết một trình phân tích cú pháp C ++ để thực thi nó.
Một quy tắc rất phổ biến cho các tệp tiêu đề là chúng phải tự đứng. Tệp tiêu đề không được yêu cầu một số tệp tiêu đề khác phải được loại trừ trước khi bao gồm tiêu đề được đề cập. Đây là một yêu cầu thử nghiệm. Đưa ra một số tiêu đề ngẫu nhiên foo.hh
, sau đây sẽ biên dịch và chạy:
#include "foo.hh"
int main () {
return 0;
}
Quy tắc này có hậu quả liên quan đến việc sử dụng các lớp khác trong một số tiêu đề. Đôi khi những hậu quả có thể tránh được bằng cách tuyên bố chuyển tiếp các lớp khác. Điều này là không thể với rất nhiều lớp thư viện tiêu chuẩn. Không có cách nào để chuyển tiếp khai báo một khởi tạo mẫu như std::string
, hoặc std::vector<SomeType>
. Bạn phải sử dụng #include
các tiêu đề STL đó trong tiêu đề ngay cả khi việc sử dụng loại duy nhất là làm đối số cho hàm.
Một vấn đề khác là với những thứ mà bạn tình cờ kéo vào. Ví dụ: xem xét các vấn đề sau:
tập tin foo.cc:
#include "foo.hh"
#include "bar.hh"
void Foo::Foo () : bar() { /* body elided */ }
void Foo::do_something (int item) {
...
bar.add_item (item);
...
}
Đây bar
là một Foo
thành viên dữ liệu lớp là loại Bar
. Bạn đã thực hiện đúng ở đây và có #included bar.hh mặc dù điều đó sẽ phải được bao gồm trong tiêu đề xác định lớp Foo
. Tuy nhiên, bạn chưa bao gồm những thứ được sử dụng bởi Bar::Bar()
và Bar::add_item(int)
. Có nhiều trường hợp các cuộc gọi này có thể dẫn đến các tham chiếu bên ngoài bổ sung.
Nếu bạn phân tích foo.o
bằng một công cụ như nm
, có vẻ như các hàm trong foo.cc
đang gọi tất cả các loại công cụ mà bạn chưa thực hiện phù hợp #include
. Vì vậy, bạn nên thêm #include
chỉ thị cho những tài liệu tham khảo bên ngoài ngẫu nhiên foo.cc
? Câu trả lời dĩ nhiên là không rồi. Vấn đề là rất khó để phân biệt các chức năng được gọi là tình cờ với các chức năng được gọi trực tiếp.