2014-07-18 73 views
0

我有幾個不同的類。很少有人需要彼此瞭解。爲了防止頭痛,我創建了一個文件來保持所有麻煩類的聲明以及適當的包含順序。在內部包含其他頭文件包含警衛導致錯誤

#ifndef GLPROJECT_H 
#define GLPROJECT_H 

class MainWindow; 
class Scene; 
class ShaderProgram; 
class Shape; 

#include "ShaderProgram.h" 
#include "MainWindow.h" 
#include "Shape.h" 
#include "Scene.h" 

#endif 

每個需要給定集合中另一個的文件都包含這個頭文件。我想出了一個主意,把所有的包括內部包括後衛,所以例如Shape.h類的樣子:

#ifndef SHAPE_H 
#define SHAPE_H 

#include "GLProject.h" //file above 

//...class definition code 

#endif 

但是這個例子產生錯誤:field ‘x’ has incomplete type ‘GLProject::Shape’文件Scene.h,這是在主標題中的Shape.h後聲明(其他文件不明確包括Scene.h)。

(請注意,下面的流程僅用於文件直接包括GLProject.h是正確的) 如果我跟蹤開始GLProject.h,然後文件列入: 1)

  1. 它包括第一標題,該標題不包括任何這些頭,
  2. 主窗口,其中包括GLProject.h但它完全被遺漏由於包括警衛,
  3. Shape.h定義Shape.h(試圖包括瓜耳後ded GLProject.h
  4. Scene.h其中聲明應該已經定義的Shape類型的變量。

所以不知道爲什麼它會抱怨Shape是不完整的類型。

What's more interesting moving inclusion of file GLProject.h in file Shape.h above include guards fixes the problem. (the most important fact)

+1

那*具體*例如不產生這樣的錯誤,至少對於*美國*。這些代碼中沒有字段'x',更不用說聲明爲未完成的類型。任何不是'MainWindow.h','ShaderProgram.h'或*其中包含的任何內容的引用或指針var的'Shape'在包含*'Shape.h'之後*之前都是不完整的(單向或其他);不是之前。我會檢查你的包括衛兵,以確保每個文件都有*獨特的*宏。 – WhozCraig

+1

你看過預處理器輸出嗎? –

+0

將所有'#include'語句放入單個文件與創建正確的前向聲明不是一回事。 'GLProject.h'作爲一個編譯器優化的編譯頭是有意義的,但它不能解決引用尚未聲明的類的問題。你仍然需要適當的前向聲明。 –

回答

1

好的。實際的問題與未提及的文件Shape.cpp有關,當然這包括Shape.h以及在警衛解決問題之前移動#include "GLProject.h"的事實。 與保護裏面的include指令流:

Shape.h (def guard) 
    GProject.h (def guard) 
      ...(MainWindow.h and ShaderProgram.h)...//not interesting 

      Shape.h (omit, because of guard) 

      Scene.h 
       GProject.h (omit, because of guard) 
      back to Scene.h (def guard) ERROR 

雖然與外界的指令:

Shape.h 
    GProject.h (def guard) 
      ...(MainWindow.h and ShaderProgram.h)...//not interesting 

      Shape.h 
       GProject.h (omit, cause of guard) 
      back to Shape.h (now def guard and class) 

      Scene.h 
       GProject.h (omit, because of guard) 
      back to Scene.h (def guard) No error - Shape defined