2011-11-22 68 views
1

我們假設有四個文件:foo.h,foo.cpp,bar.h,bar.cpp。VC++ 2010:'缺少類型說明符'錯誤來來去去,沒有改變代碼

foo.h中:

#pragma once 

class foo 
{ 
    // Whatever 
}; 

Foo.cpp中

#include "foo.h" 

// Foo's definitions 

bar.h

#pragma once 

class bar 
{ 
    bar(const foo & f); // < C4430 'missing type specifier' (not always) 
    // Other declarations 
}; 

bar.cpp

#include "foo.h" 
#include "bar.h" 

// Bar's definitions 

編譯器說有C4430在bar.h.但奇怪的是,我可以通過評論來構建代碼,然後取消註釋。當然,構建失敗,行也被評論,但是當我取消註釋時,我會成功構建。所以相同的代碼可能會或可能不會產生錯誤。

我的VS是10.0.40219.1 SP1Rel,並且項目類型是Win32 DLL。

回答

2

您需要包括foo.hbar.h

#pragma once 

#include "foo.h" 
class bar 
{ 
    bar(const foo & f); 
}; 

如果你需要一個完整的類定義,你這樣做,除非你使用指針(在這種情況下,預先聲明就足夠了),你需要包括聲明類的文件。

爲什麼有時會編譯,有時會失敗?

取決於編譯器。我的猜測是foo.h包含在達到bar.h之前編譯的文件中。所以bar.h已經知道foo的定義。如果構建失敗,則跳過已成功編譯的文件,並且可能不再包含foo.h。或者,如果僅在x.cpp中進行更改,則編譯器將只生成該文件並可能跳過包含在已編譯文件中的foo.h

我希望我很清楚。

爲什麼你已經擁有的是不夠的?

你也許會說

//Bar.cpp 
#include "foo.h" 
#include "bar.h" 

// Bar's definitions 

包括foo.hbar.h之前。事實上,但如果bar.hfoo.h之前包含在不同的地方呢?這就是爲什麼在bar.h中包含foo.h是一個好主意。包括bar.h在內的任何文件都不再需要包含foo.h(它必須爲了編譯),並且在文件中包含所需的所有內容會更有意義。前向聲明並不是這種情況,但同樣,你使用的是完整類型,而不是指針。

+0

儘可能清楚!非常感謝Luchian! – Yegor

+0

@Yegor樂於幫助:) –

+0

如果您只使用引用,而不僅僅是指針,那麼聲明也足夠。 – Xeo

相關問題