2010-10-27 41 views
2

以下代碼:C++編譯錯誤枚舉 「沒有指定類型」

foo.h中

#include "bar.h" 
class foo{ 
public: 
    enum my_enum_type { ONE, TWO, THREE }; 
    foo(); 
    ~foo() {} 
}; 

Foo.cpp中

foo::foo() 
{ 
    int i = bar::MY_DEFINE; 
} 

bar.h

#include "foo.h" 
class bar{ 
public: 
    static const int MY_DEFINE = 10; 
    foo::my_enum_type var; 
    bar() {}; 
    ~bar() {}; 
}; 

使g ++編譯器抱怨my_enum_type「沒有命名一種」。 爲什麼? 所有標題都有多個包含定義(爲清晰起見,此處未顯示)。

感謝

+1

這應該很好...... – 2010-10-27 10:28:50

+1

你如何使用這些類?您在這裏還沒有源文件。你能分享你如何使用這些類嗎? – 2010-10-27 10:30:57

+1

謝謝你們,你讓我意識到問題不在於語法,而在於我如何使用這些類。在foo.h中有一個#include「bar.h」,我用一個前向聲明取代了它,現在一切正常! – 2010-10-27 10:35:17

回答

2

您必須刪除循環依賴,因此您需要將foo.cpp和foo.h作爲不同的單位來實現此目的。

  • bar類定義必須看到foo :: my_enum_type,因此可能bar.h包括foo.h是必需的。

  • Foo類定義不使用任何酒吧,因此foo.h中並不需要包括bar.h

  • Foo.cpp中確實需要看到巴MY_DEFINE所以Foo.cpp中應包括酒吧。 H。這實際上也會自動引入foo.h,但是您可能希望將其包含在foo.cpp中,以防萬一您稍後再刪除依賴項。

大概你的標題有多個包含的警衛。

+1

我不知道你必須分別考慮.h和.cpp依賴。我認爲在.cpp中包含多個.h是糟糕的設計。我可能是錯的,你的答案解決了我的問題。謝謝 :) – 2010-10-27 13:26:01

4

問題:

  • 沒有多重保護納入
  • 循環列入
  • 造成循環納入其聲明之前
  • 使用類型

正在處理您的了foo.h由C預處理器看起來像無限的空字符串序列。

隨着多次包含保護foo.h中進行預處理,以:

> cpp foo.h 
class bar{ // preprocessed from #include "bar.h" 
public: 
    static const int MY_DEFINE = 10; 
    foo::my_enum_type var; 
    bar() {}; 
    ~bar() {}; 
}; 
// end of #include "bar.h" 
class foo{ 
public: 
    enum my_enum_type { ONE, TWO, THREE }; 
    foo(); 
    ~foo() {} 
}; 

這顯然不是一個有效的C++代碼 - foo是酒吧的身體沒有使用以前聲明。與Java不同,C++需要在使用之前聲明類型。

  • 使用多重包含保護。根據您的平臺,這些可能是#ifndef宏或#pragma once指令
  • 從foo.h中刪除bar.h包含。
  • 在需要的地方放置轉發聲明(在你的情況下,bar可能會在foo.h中聲明,你的例子雖然沒有揭示這個的必要性)。
  • 將盡可能多的實現移至* .cpp文件。

如果使用這些建議無法解決問題,請使用PIMPL idiom

總之 - 剛剛從foo.h中

刪除 #include "bar.h"指令
+0

我的標題有多個包含保護。如果我從foo.h中刪除bar.h,foo.cpp不能再使用bar :: MY_DEFINE('bar'還沒有被聲明)。 – 2010-10-27 13:20:26

+0

錯誤。如果在foo.cpp中包含bar.h,foo.cpp仍然可以使用bar。 – Basilevs 2010-10-27 15:18:40

+0

是的,這就是我不知道的;) – 2010-10-27 16:16:06

2
foo() 
{ 
    int i = bar::MY_DEFINE; 
} 

應該

foo::foo() 
{ 
    //... 
} 

還要注意的是

static const int MY_DEFINE = 10; 

仍然是一個聲明,雖然它有一個初始化。在酒吧。CPP你應該有以下行

const int bar::MY_DEFINE; 

您也可以不包括來自bar.h了foo.h和foo.h中bar.h ...這就是物理上是不可能:)