2011-11-22 65 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

相关问题