2012-03-12 115 views
1

因此可以说我有一个名为Foo的类和另一个名为BarBar包含Foo的实例,我在Foo中有一个函数,它将Bar作为参数。然而,当我在#include "Bar.h"Foo允许Foo看到Bar我上线这个错误Bar上引用:#include彼此的两个类的错误

error: ISO C++ forbids declaration of 'Foo' with no type

我猜这是因为这两个阶级的互相依赖编译。有什么办法可以解决这个问题吗?

编辑:这两个类都有头文件,其他类在#ifndef声明中引用。

+7

如果你必须包括其他类,你应该过度考虑你的程序设计。这里不对劲。 – 2012-03-12 06:24:16

+0

考虑预处理器的输出结果。弄清楚它应该是什么样子,这是告诉哪些头文件不需要包含另一头文件的巨大举措。 – hvd 2012-03-12 06:26:14

+0

如果一个类体尚不可见,那么你需要转发声明它。但是,只能使用前向声明才能使用该类的对象。你需要让类体可见才能拥有它的对象。 – iammilind 2012-03-12 06:26:42

回答

3

Foo.h而不是包括Bar.h您需要使用正向声明class Bar;。请注意,为此,您需要将参数Bar作为参考或Foo类中的指针。

+0

在'struct bar; struct foo {void frob(bar); };','bar'不一定是完整的。只有当你需要定义一个成员变量时,你需要有一个完整的类型(否则编译器将无法计算'foo'的大小)。 – 2012-03-12 06:27:58

0

使用引用或指针进行参数和前向声明。例如。

//foo.h 
class Bar;// the forward declaration 
class Foo { 
void myMethod(Bar*); 
}; 

//foo.cpp 
#include "bar.h" 
void Foo::myMethod(Bar* bar){/* ... */} 

//bar.h 
#include "foo.h" 
class Bar { 
    /*...*/ 
    Foo foo; 
}; 
0
class Foo; 

class Bar 
{ 

}; 

and 

class Bar; 
class Foo 
{ 
}; 

但是,这可能是一个错误的设计的结果!

+0

一堆没有圆形的类也可能是错误设计的结果。循环性不会成为糟糕设计的标志。 – Kaz 2012-03-12 07:33:46

+0

但是,如果可以的话,我们试图避免这种情况吗? – 2012-03-12 07:40:13

0

你需要使用一个向前声明至少一个类:

了foo.h:

#include "Bar.h" 

class Foo { 

}; 

Bar.h:

class Bar; 

#include "Foo.h" 

class Bar { 

}; 

另外注意你不能轻易地引用Foo.h中Bar的成员(他们没有声明)。因此,任何需要Bar的内联成员都必须使用Foo.cpp(如果您愿意,可以使用.cc)。你也不能有一个酒吧作为Foo的价值成员。

所以:

class Bar { 
    Foo f; // OK. Compiler knows layout of Foo. 
}; 

class Foo { 
    Bar b; // Nope. Compiler error, details of Bar's memory layout not known. 
    Bar *b; // Still OK. 
}; 

这对于模板尤其棘手。如果遇到麻烦,请参见FAQ