2013-08-31 299 views
3

我正在開發一個項目,每個頭文件都有一個預處理程序include guard。 我包括由這樣的:C++頭文件包含

(文件 - >包括)

的main.cpp - > header.h; Character.h

header.h - >載體的iostream,...,DataFiles.h

Character.h - > DataFiles.h,header.h,CharFrame.h

CharFrame.h - > DataFiles.h,header.h

一切工作正常。但是,如果我只是擦除main.cpp的#include「Character.h」以將其移到header.h中,那麼在編譯時會出現很多錯誤。所以,現在,它是:

的main.cpp - > header.h

header.h - > ...,DataFiles.h,Character.h。

有什麼區別?

這裏是我的compilator輸出:

Inspiron-1545:~/Desktop/LF2_linux$ g++ -Wall main.cpp DataFiles.cpp header.cpp Character.cpp CharFrame.cpp -lSDL -lSDL_image -lSDL_ttf -o test 
In file included from header.h:13:0, 
      from CharFrame.h:12, 
      from CharFrame.cpp:1: 
Character.h:55:15: error: ‘CharFrame’ was not declared in this scope 
Character.h:55:25: error: template argument 1 is invalid 
Character.h:55:25: error: template argument 2 is invalid 

如果包括被放回的main.cpp,然後它編譯沒有任何錯誤。

如果您覺得我的代碼是必需的,我會編輯這篇文章並粘貼所有內容。

這裏有感興趣的線路:

header.h:13 -> 
#include "Character.h" 
CharFrame.h:12 -> 
#include "header.h" 
CharFrame.cpp:1 -> 
#include "CharFrame.h" 
Character.h:55 -> 
std::vector <CharFrame*> *frame; 
+0

聽起來像'header.h'使用'CharFrame',但它被包含(使用)在'CharFrame'聲明之前的'CharFrame.h'中。所以編譯器在聲明之前就嘲諷了'CharFrame'。 –

+0

如果你正在做你說的話,應該沒有區別。但由於某些原因,編譯器無法識別「CharFrame」類型。你可以發佈[SSCE](http://sscce.org/)來重現此問題嗎? – Mahesh

+0

DataFiles.h是否包含其他的? –

回答

5

你改變Character.h和header.h之間創建了一個包含循環。

據推測,Character.h依賴於headers.h中的一些聲明。現在,你的變化,會發生以下情況:

  1. headers.h包括,定義了包括後衛和預處理開始檢查其內容。

  2. headers.h包含Character.h,然後它進行自己的聲明。

    1. Character.h定義了它的包含guard,預處理器讀取它的內容。

    2. Character.h包含header.h以獲取所需的定義。

      1. headers.h然而看到它的包含守衛,並被解析爲空。尚未定義。
    3. 讀取Character.h定義。

  3. headers.h定義被讀取。

正如你所看到的,Character.h中的定義是在它們依賴的header.h中的定義之前被讀取的。

修復循環包含的最佳方法是儘可能用前向聲明替換#include。在某些罕見情況下,可能需要將聲明與包含實際混合使用,但是您應該不惜一切代價避免這種情況。

+0

感謝這完成了khajvah鏈接中的解釋,其中的例子讓#include s不應該像剛剛所說的那樣:) –