2013-05-06 201 views
0

Main.cpp的循环包括在C++ - 再次

#include "Test1.h" 
#include "Test2.h" 

int main(){ 
    Test1 t1; 
    Test2 t2; 

    t1.process(t2); 
    t2.process(t1); 

} 

Test1.h

#ifndef TEST1 
#define TEST1 

#include "Test2.h" 

class Test1 { 
public: 
    void process(const Test2& t) {}; 
}; 


#endif // !TEST1 

Test2.h

#ifndef TEST2 
#define TEST2 

#include "Test1.h" 

class Test2 { 
public: 
    void process(const Test1& t) {}; 
}; 


#endif // !TEST2 

VS2012说:

error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
error C2143: syntax error : missing ',' before '&' 
error C2664: 'Test2::process' : cannot convert parameter 1 from 'Test1' to 'const int' 

我敢肯定它是圆形包括问题又来了(我在一段时间遇到一次),但这次我不知道为什么不能做到这一点的编译。

注意:这些类只依赖于彼此的引用,它们的大小已知。是否因为包含卫士(#ifndef),使得其中一个Test头包含另一个为空文件?

+5

为什么你需要在所有的包括哪些内容?前缀声明在'* .h'中都是足够的。 – kennytm 2013-05-06 18:10:05

+1

有数以百万计的重复。在发布之前花点功夫去研究这个问题。 – 2013-05-06 18:10:29

+0

看[这里](http://stackoverflow.com/questions/553682/when-to-use-forward-declaration),很好的解释。在决定是转发声明还是包含时,可以将其用作经验法则​​。 – 2013-05-06 18:10:56

回答

1

完全展开的预处理指令,你会看到这个问题:Main.cpp的包括Test1.h包括Test2.h,所以class Test2将首先被编译,之前曾经定义Test1,导致missing type specifier错误。您可以通过向前声明Test1并说void process(const class Test1& t)而不仅仅是void process(const Test1& t)来解决此问题。

+0

但为什么我需要在Test2中定义Test1,我只在方法签名中使用引用;它的大小已知。我甚至不会调用任何方法 – 2013-05-06 18:18:21

+0

对于C++来说这还不够;它不知道'Test1'在那个时候是什么,所以它不知道它是一个类型还是别的。当然,C++可以推断'Test1'是一种类型,但这不是语言设计的方式。你必须明确地说'Test1'是一种类型,然后才能使用它;要么完全声明类型,要么将其声明为类型。 – 2013-05-06 18:21:43

3

如果你坚持这样做,你需要在每个.h文件中声明你的类,以便编译器知道它是什么。

#include "Test1.h" 

class Test1; 

class Test2 { 
public: 
    void process(const Test1& t) {}; 
}; 
+0

正向声明'class Test1'允许你声明指向Test1的指针,而不是实现引用。 '#include '在这里看起来不太合适。 – 2013-05-06 18:12:31

+0

@CaptainGiraffe:“实施参考”甚至意味着什么? – 2013-05-06 18:13:11

+0

问题关闭太快,我无法调整任何东西。好吧。 – 2013-05-06 18:13:31

0

您需要将其中一个的前向声明放在另一个的头部中。如果你在Test2.h中声明Test1(在声明Test2之前),你可以从Test2.h中删除#include "Test1.h"

0

如果你有一个引用或指向一个头部类型的指针,只要尝试使用一个前向声明即可。

// Within stop Test2.h 
class Test1; 
0

test1.htest2.h您可以分别使用Test2Test1的前向声明来避免包含。只需将class Test1;代替#include "test1.h"即可。

然后在执行文件中只包含test1.h

看到这个question