这是代码:
class B
{
A a;
};
class A
{
B b;
};
int main()
{
return 0;
}
这是错误:
1>c:\mine\visual studio 2010 projects\myproj\compiled equivalent.cpp(7):
error C2079: 'B::a' uses undefined class 'A'
你不能。两个类不能作为成员相互包含。考虑回答“类型的大小是A
多少?”这个问题。井A
包含一个B
,那么 的大小是B
多少?井B
包含一个A
,那么 的大小是A
多少?哦,天哪,我们有一个无限循环。我们如何将这个对象存储在有限的内存中?
也许更合适的结构是让其中一个类包含指向另一种类型的指针。指向的类型可以在声明指针成员之前简单地向前声明:
class A; // A is only declared here, so it is an incomplete type
class B
{
A* a; // Here it is okay for A to be an incomplete type
};
class A
{
B b;
};
现在该类型B
不包含 an A
,它只包含一个指向an的指针A
。它甚至不需要A
指向一个对象,所以我们打破了无限循环。
考虑到您要求在类之间进行引用,可能您来自 Java、C# 或类似的背景,其中一个人只能将对象的引用放在其他对象中。
在 C++ 中没有这样的限制:您可以将一个对象的内容完全嵌套在另一个对象中。但要使其工作,您必须事先提供嵌套对象的定义。C++ 需要这个定义来计算外部对象的大小和布局。为了摆脱这种嵌套,您不需要放置对象本身,而是将指针或引用放置在外部对象内。
话虽如此,
// C#
class A
{
int x;
B b;
}
class B
{
int y;
A a;
}
变成
// C++
class B; // tell the compiler that B is a class name
class A
{
int x;
B *pb; // the forward declaration above allows you to declare pointer to B here
};
class B
{
int y;
A *pa;
};
如果您决定使用指针语法。
这允许的是具有以下内容:
// C++ again
class C
{
A a;
B b;
A *pa2;
};
它具有以下形式的内存布局:
C: a.xa.pb b.yb.pa pa2
这在 Java/C# 中是不可能的。