2011-01-22 85 views
25

At LearnCpp.com | 1.10 — A first look at the preprocessor。下部首警衛,還有那些代碼片斷:C++中的標題警衛

add.h:

#include "mymath.h" 
int add(int x, int y); 

subtract.h:

#include "mymath.h" 
int subtract(int x, int y); 

main.cpp中:

#include "add.h" 
#include "subtract.h" 

在實施頭衛隊,它提到如下:

#ifndef ADD_H 
#define ADD_H 

// your declarations here 

#endif 
  • 什麼能申報在這裏?而且,int main()之後是#endif
  • 是否添加_H約定或必做的事情?

謝謝。

+0

那麼,上面實現的頭部gurad是否插入了「add.h」? – Simplicity 2011-01-22 09:47:54

回答

1

不,int main()進入.cpp。聲明是你要放在標題中的其他內容。 _H是一個約定,你可以看到各種各樣的標題守衛約定。

3

所有標頭守衛都只允許您的標題包含一次。 (如果它們被多次包含,它們將被忽略。)

您使用的名稱無關緊要,但是在大寫字母中使用文件名是常規操作,包括像您演示的擴展名。

您的main應該確實在.cpp文件中,但是如果您將它放在標題中,請將它放在警衛內部,以免它多次聲明。

+0

感謝您的回覆。但是,對於「mymath.h」,這裏不是問題,並且在「main.cpp」中包含它兩次,因爲我們有兩個包含「add.h」和「subtract.h」的內容? – Simplicity 2011-01-22 09:50:14

+0

是的,的確如此。這就是爲什麼你應該在那裏放置一個`MATH_H`後衛。 (我不確定我是否正確理解你的問題......) – Mehrdad 2011-01-22 09:56:33

+0

你在哪裏指「在那裏」?你的意思是mymath.h嗎? – Simplicity 2011-01-22 17:09:28

46

FILENAME_H是一個慣例。如果你真的想要,你可以使用#ifndef FLUFFY_KITTENS作爲頭部守衛(如果沒有在其他地方定義的話),但是如果你把它定義在其他地方,比如某些東西或其他東西的數量,這將是一個棘手的錯誤。

在頭文件add.h中,聲明字面上在#ifndef#endif之間。

#ifndef ADD_H 
#define ADD_H 

#include "mymath.h" 
int add(int x, int y); 

#endif 

最後,int main()不應該在頭文件中。它應該始終在.cpp文件中。

把它清除掉:

#ifndef ADD_H基本上意味着「如果ADD_H尚未在文件中或在被包含的文件#defined,然後編譯#ifndef#endif指令之間的代碼」。因此,如果您在.cpp文件中多次嘗試#include "add.h",編譯器將會看到ADD_H已是#defined,並將忽略#ifndef#endif之間的代碼。標題保護僅防止在同一個.cpp文件中多次包含頭文件。標題保護不會阻止其他.cpp文件包含頭文件。但是所有.cpp文件只能包含保護標頭文件一次

1

我在頭文件中聲明一個聲明和定義或者int main()進來source.cpp文件。

_H是否僅僅表明某人將使用包含警衛來包含頭文件。

如果你在MSVC++,你也可以使用#pragma once

17
  • 預處理一個執行的結果( 「的.cpp」)文件是一個翻譯單元(TU)。

  • 標題可以包含其他標題,因此標題可能在同一個TU中間接包含多次。 (您的mymath.h就是一個例子。)

  • 定義每TU最多隻能發生一次。 (有些定義也不能在多個TU中;這種情況稍有不同,此處不予討論)

  • 問題包括警衛解決方案是在一個TU內多次包含給定頭時防止出現多重定義錯誤。

  • 包括警衛通過「包裝」標題的內容以使第二個和隨後的包含爲空操作的方式工作。 #ifndef /#define指令應該是文件的前兩行,並且#endif應該是最後一行。

  • 包括守衛只用於標題。不要在頭文件中定義主函數:將其放入實現文件中。

如果你有一個頭,將定義類型和聲明的功能,還需要一個頭本身:

#include "other_header.h" 

struct Example {}; 

void f(); 

「包裝」它包括守衛給出了文件的全部內容:

#ifndef UNIQUE_NAME_HERE 
#define UNIQUE_NAME_HERE 

#include "other_header.h" 

struct Example {}; 

void f(); 

#endif 

用於包含警衛的名稱必須是唯一的,否則衝突的名稱會給出令人困惑的結果。這些名稱只是簡單的宏,並且在執行某種風格的語言中沒有任何內容。但是,項目公約通常會強制要求。在SO和其他地方可以找到幾種不同的警衛命名風格, this answer提供了很好的標準和良好的概述。