2013-08-02 25 views
4

我得到這個編譯器錯誤「不命名類型」錯誤,但類指針已經有前向聲明?

error: 'RawLog' does not name a type 

下面是相關代碼:

//DataAudit.h 
#ifndef DATAAUDIT_H 
#define DATAAUDIT_H 

class RawLog; 

class DataAudit 
{ 
... 
private: 
    RawLog* _createNewRawLog(); // This is the line indicated with the error 
}; 

#endif // DATAAUDIT_H 

通常預先聲明解決了這樣那樣的錯誤。 This答案表示一個循環的頭文件包含可能會導致此問題。但是否使用#ifndef#define語句防止循環標題包含?

是否有另一個原因,我可能會看到這個錯誤?

有什麼方法可以用來進一步推斷此錯誤的性質?

更新:這很奇怪。我有一個Globals.h文件,如果我在Globals.h中定義新的enum,則會顯示錯誤。然後,如果我註釋掉enum,錯誤消失。這導致我認爲循環依賴已經存在了一段時間,並且添加enum以某種方式重新排序編譯單元,從而暴露之前沒有的依賴性?

+0

您確定這確實是問題所在,並且您給了我們一個完整且可重複的示例嗎?如果是這樣,什麼編譯器,因爲g ++ 4.6.3編譯它很好[一旦我添加缺少分號並刪除...]。 –

+0

你也在DataAudit的最後忘了';'。取決於如何包括這些可能會導致問題。 – Borgleader

+0

@Borgleader啊,我的壞。分號在原代碼中。 –

回答

2

最後,我不確定我完全理解錯誤發生的原因,但這是我所做的解決它和其他一些相關信息。也許這會幫助其他人解決這個問題。

  1. 對於頭
    1. 如果有在#include到類沒有引用我的項目
      1. 每個頭文件對每個#include "...",將其刪除。
      2. 如果只有指向#include中定義的類的指針,則將其替換爲class ...前向聲明。
      3. 如果存在#include中定義的類的成員實例,並且使用指針並在堆上分配成員是有意義的,那麼將該成員更改爲指針,並用class ....前向聲明替換#include
  2. 經過我Globals.h和移動任何可以被移出它更加本地化和特定的頭文件。
    1. 具體而言,刪除定義的enumGlobals.h,並將其置於更加本地化的頭文件中。

做的這一切,我能夠讓錯誤消失後。奇怪的是,enumGlobals.h似乎是一個錯誤的催化劑。每當我從Globals.h中刪除它時,錯誤都會消失。我不明白這個enum可能會導致錯誤,所以我認爲它以某種方式間接導致了錯誤。我仍然無法弄清楚究竟是如何或爲什麼,但它在C++編程中幫助了我的指導原則:

不要在頭文件中放置任何東西,除非它需要在那裏。不要 將任何內容放置在Globals.h中,該文件可放置在更加本地化的 文件中。基本上,盡你所能減少通過#include指令包含的代碼量 。

+0

需要注意的是,上面的'1.1.3'可能是一個有爭議的設計決策,但是當您進入第4個小時調試類似的錯誤時,只需稍做設計更改即可解決您的問題,這可能是值得的。 –

3

#ifndef頭部防護不防止循環依賴性。它只是防止在單個文件中包含多個相同頭文件。

看起來像一個循環依賴於我。這意味着你在DataAudit.h中直接或間接地獲得了DataAudit.h中的頭文件#include