2011-02-01 36 views
16

C++ bao gồm bộ bảo vệ thường được đặt tên như thế nào? Tôi có xu hướng thấy điều này rất nhiều:Đặt tên bao gồm các vệ sĩ

#ifndef FOO_H 
#define FOO_H 

// ... 

#endif 

Tuy nhiên, tôi không nghĩ điều đó rất trực quan. Nếu không nhìn thấy tên tệp thì rất khó để biết được những gì FOO_H có và tên của nó là gì.

Phương pháp hay nhất là gì?

+2

Trong khi tên có thể được nhiều hơn hoặc ít trực quan, thực tế là với một chút kinh nghiệm bạn ngừng đọc những dòng đó. Đôi mắt và bộ não quen thuộc với '#ifdef blahblah ...' và tôi hầu như không bao giờ thực sự đọc những gì đang được kiểm tra, nó là một bảo vệ bao gồm. –

+3

Một quan điểm hữu ích về vấn đề này: http://stackoverflow.com/questions/1744144/adding-an-include-guard-breaks-the-build/1744302#1744302 –

+0

Bất kỳ ai làm phát triển C++ đều đã quen với việc nhận ra các tiêu đề bảo vệ rất nhanh. Nó sẽ luôn tuân theo tiêu chuẩn bạn đang thấy. "Tốt nhất" thực hành (trong dấu ngoặc kép vì nó được yêu cầu) là để đặt ifndef đầu tiên, xác định ngay lập tức sau, và kết thúc nó ở phần cuối của tập tin. Tôi đề nghị bạn học cách nhận ra điều này càng sớm càng tốt. –

Trả lời

15

Từ kinh nghiệm của riêng tôi, quy ước là đặt tên cho bộ bao gồm sau khi tệp tiêu đề chứa chúng với ngoại lệ là tên được viết hoa và dấu chấm được thay thế bằng dấu gạch dưới.

Vì vậy, test.h trở thành TEST_H.

Ví dụ thực tế về điều này bao gồm Qt Creator, tuân theo quy ước này khi tự động tạo tệp tiêu đề lớp.

+4

Thật tuyệt khi chỉ sử dụng FILENAME_H làm tên bảo vệ bao gồm vì bạn giữ tất cả các tệp cho tất cả các dự án và tất cả thư viện trong cùng thư mục không có thư mục con, vì vậy bạn biết chúng không bao giờ có tên tệp xung đột ... –

+2

, nó có thể không đủ tốt, tùy thuộc vào những gì khác cửa hàng của bạn làm với #defines và tên khác. –

1

Tôi thường sử dụng một cái gì đó như FOO_H_INCLUDED_. Một vài (Microsoft) tiêu đề có những gì trông rất giống như một chuỗi đại diện của một GUID, nhưng tôi đã không bao giờ cần bất cứ điều gì khá phức tạp.

3

Thay thế FOO_H bằng FOO_H_INCLUDED và rõ ràng hơn.

1

Thông thường mọi người làm điều đó theo tên tệp sao cho mỗi mã của tệp chỉ được biên dịch và thêm một lần. Bạn có thể làm cho FOO_H bất cứ điều gì bạn muốn, nhưng hầu như tất cả mọi thứ tôi đã từng mã hóa hoặc nhìn thấy đã sử dụng tên tập tin. Chỉ cần chắc chắn rằng nó là duy nhất bởi vì bạn không muốn xung đột FOO_H của bạn với FOO_H của người khác.

10

Taken trực tiếp từ google's style guide:

Tất cả các tập tin tiêu đề nên có #define bảo vệ để ngăn chặn nhiều nhận. Định dạng của tên biểu tượng phải là là < DỰ ÁN> _ < PATH> _ < TẬP_TIN> _H_. Để đảm bảo tính duy nhất, chúng phải là dựa trên đường dẫn đầy đủ trong cây nguồn của dự án là . Ví dụ, các tập tin foo/src/bar/baz.h trong foo dự án nên có bảo vệ sau:

#ifndef FOO_BAR_BAZ_H_ 
#define FOO_BAR_BAZ_H_ 
... 
#endif // FOO_BAR_BAZ_H_ 

tôi sử dụng phong cách này trong các dự án của riêng tôi.

+5

Mặc dù nói chung các tiêu chuẩn mã hóa google là một trong những tồi tệ hơn tôi từng thấy, tôi làm tiền tố với không gian tên. Nó hoàn toàn cần thiết nếu bạn có bất cứ thứ gì có cùng tên trong nhiều không gian tên. –

+0

Tôi đã cố gắng tìm ra, có bất kỳ lý do nào đằng sau dấu gạch dưới sau không? – Toby

+1

@Toby Chỉ để làm cho nó (thêm) độc đáo ...Nếu ai đó có 'CONFIG_H' (như một thư viện được đưa vào, ví dụ) thì sử dụng' CONFIG_H_' sẽ không đụng độ với nó. Cùng lý do một số người sử dụng một gạch dưới hàng đầu, nhưng họ không nên vì thags reserved. – RastaJedi

1

Tôi thường xem thời gian là gì và chỉ cần gắn thêm vào cuối, tức là FOO_H_248, đó là một biện pháp phòng ngừa thêm và bạn sẽ không bao giờ phải nhớ nó, vì vậy bạn không cần phải lo lắng về thực tế là nó khó hiểu.

+0

Bạn có sử dụng đồng hồ 12 hoặc 24 giờ và giờ địa phương này không? ;-) – T33C

+5

@ T33C: 12? 24? Bạn đang nói về cái gì vậy? Nó chỉ là một chiếc đồng hồ 17 giờ bình thường. Và đó là thời gian địa phương để bất cứ nơi nào Đức Giáo Hoàng là tại thời điểm đó. –

2

Như những người khác đã đề cập trước, một quy ước rất phổ biến là sử dụng phiên bản chữ hoa của tên, và dấu chấm thay thế bằng một dấu gạch dưới: foo.h -> FOO_H

Tuy nhiên, điều này có thể dẫn đến xung đột tên với tên đơn giản và/hoặc thông thường. Vì lý do này, tiêu đề autogenerated như stdafx.h vào các dự án không rỗng Visual C++ C thêm một số chuỗi ngẫu nhiên, như:

#ifndef FOO_H__NsknZfLkajnTFBpHIhKS 
#define FOO_H__NsknZfLkajnTFBpHIhKS 
#endif 

http://www.random.org/strings/ là một máy phát ngẫu nhiên hữu ích cho việc này.

Ngoài ra, nếu tập tin là một phần của một số submodule, hoặc nội dung của nó cư trú trong một không gian tên cụ thể, tôi có xu hướng thêm rằng để bảo vệ quá:

#ifndef SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS 
#define SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS 

namespace somecomponent 
{ 
    ... 
} 

#endif 
+4

Đây là những tên được đặt trước vì dấu gạch dưới kép. Vì vậy, KHÔNG thực hành tốt để sử dụng điều đó. –

4

Nhìn vào mã # bao gồm tiêu đề của bạn .

Nếu nó là một cái gì đó như:

#include "mylib/myheader.h" 

mylib/myheader.h đã là một cái tên độc đáo. Chỉ viết hoa và thay thế/và. với _

#define MYLIB_MYHEADER_H 

Nếu bạn có hai tiêu đề trên đường dẫn có cùng tên liên quan đến đường dẫn bao gồm, bạn đã có xung đột ở cấp đó.

16

Cá nhân tôi thực hiện theo đề xuất của Boost. Nó có lẽ là một trong những bộ sưu tập lớn nhất của các thư viện C++ có chất lượng tốt và không có vấn đề gì.

Nó đi như:

<project>_<path_part1>_..._<path_partN>_<file>_<extension>_INCLUDED 

// include/pet/project/file.hpp 
#ifndef PET_PROJECT_FILE_HPP_INCLUDED 

đó là:

  • quy phạm pháp luật (chú ý đầu rằng bằng cách _[A-Z] hoặc chứa __ không phải là)
  • dễ dàng để tạo
  • đảm bảo là duy nhất (như một bảo vệ bao gồm) trong một dự án (nếu bạn có hai tập tin ở cùng một nơi)
  • đảm bảo không được sử dụng cho bất kỳ điều gì khác (nếu bạn kết thúc một macro khác với INCLUDED bạn đang tha hồ chiến đấu)

Tôi đã đọc về GUID nhưng những điều này thật lạ.

Và rõ ràng là tôi muốn chứ không phải tất cả các trình biên dịch thực hiện #pragma once (hoặc tốt hơn, #pragma multiple và "một lần" là hành vi mặc định ...)

+0

Cá nhân, tôi cảm thấy rằng việc thêm tiện ích mở rộng là thừa, nhưng tôi thích cách thức _INCLUDED thực sự nói điều gì là viết tắt của nó, +1 cho điều đó. Sở thích của tôi là sử dụng INCLUDE_GUARD_FOO (không có dư thừa _H, chúng tôi chỉ cần bao gồm cả bảo vệ cho các tiêu đề, sau khi tất cả) mà thậm chí còn nhiều hơn một chút cho điểm imho, nhưng đó là một vấn đề của hương vị, thực sự. – cmaster

+0

@cmaster Việc bổ sung _H có thể hữu ích trong các tình huống mà bạn có C và C++ thực hiện một số chức năng (sử dụng tệp .h và .hpp tương ứng). – Squirrel

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