以下代码在VC ++ 6中编译。我不明白为什么我收到以下代码的编译错误C2079: 'b' uses undefined class 'B'
。
B类来源
#include "B.h"
void B::SomeFunction()
{
}
B类标题
#include "A.h"
struct A;
class B
{
public:
A a;
void SomeFunction();
};
struct A Header
#include "B.h"
class B;
struct A
{
B b;
};
如果我将B类标题更改为以下内容,则不会出现错误。但标题声明不会在顶部!
带有奇怪标题声明的B类标题
struct A;
class B
{
public:
A a;
void SomeFunction();
};
#include "A.h"
答案 0 :(得分:16)
为了定义类或结构,编译器必须知道类的每个成员变量有多大。前瞻性声明不会这样做。我只看到它用于指针和(较少经常)引用。
除此之外,你在这里尝试做的事情是无法做到的。您不能拥有包含另一个类B的对象的A类,其中包含A类的对象。可以,但是,有类A包含一个指针到B类,其中包含A类的对象。
<强> B.cpp 强>
#include "B.h"
void B::SomeFunction()
{
}
<强> B.h 强>
#ifndef __B_h__ // idempotence - keep header from being included multiple times
#define __B_h__
#include "A.h"
class B
{
public:
A a;
void SomeFunction();
};
#endif // __B_h__
<强> A.H 强>
#ifndef __A_h__ // idempotence - keep header from being included multiple times
#define __A_h__
#include "B.h"
class B; // forward declaration
struct A
{
B *b; // use a pointer here, not an object
};
#endif // __A_h__
两点。首先,请确保使用某种形式的幂等性来防止每个编译单元多次包含标头。其次,要理解在C ++中,类和结构之间的唯一区别是默认的可见性级别 - 默认情况下,类使用私有可见性,而默认情况下结构使用公共可见性。以下定义在C ++中在功能上是等效的。
class MyClass
{
public: // classes use private visibility by default
int i;
MyClass() : i(13) { }
};
struct MyStruct
{
int i;
MyStruct() : i(13) { }
};
答案 1 :(得分:4)
转发声明,例如
struct A;
或
class A;
将A作为不完整类型引入,并且在到达类型定义的结尾之前它仍然是不完整的。你可以用不完整的类型和你不能做的事情来做。你可以
你不能
在您的代码中,您尝试声明不完整类型的struct成员。这是非法的。只允许指针和引用。
答案 2 :(得分:3)
public:
A a;
您正在尝试仅使用前向声明创建A的对象。此时编译器(仅使用forward decl)无法决定对象A的大小,因此无法分配A所需的内存。因此,您无法创建仅具有前向decl的对象。
取而代之的是:
A* a;
没有A的类定义的指针或A的引用将正常工作。
答案 3 :(得分:2)
这里有两个问题突然出现在我身上。
1:您已经写过Struct A
而不是struct A
;注意小写的“s”。您的编译器可能会考虑等效的,但我认为它不是标准的C ++。
您已在A
和B
之间定义了循环引用。每个A对象必须包含一个B
对象,但每个B
对象必须包含一个A
对象!这是一个矛盾,永远不会按照你想要的方式工作。解决该问题的常用C ++方法是使用A::b
或B::a
(或两者)的指针或引用。
答案 4 :(得分:0)
你还可以包括B.h的A.h和A.h.的B.h.您至少应该使用预处理器宏:
#ifndef __A_H__
#define __A_H__
// A.h contents
#endif
这样该文件不会被包含多次。
答案 5 :(得分:0)
如果你创建一个A的实例,它将创建一个B(成员var)的实例,它将创建一个A(成员var)的实例,它将创建一个B的实例,它将创建一个A的实例,依此类推... 编译器不应该允许这样做,因为它需要无限的内存。
要解决此问题,A或B必须使用指向另一个类的引用/指针。