如何处理相互引用的类?

时间:2013-05-10 22:03:19

标签: c++ class

以下是代码:

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'

2 个答案:

答案 0 :(得分:8)

你做不到。两个类不能作为成员相互包含。考虑回答“类型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不包含A,它只包含A指针。甚至没有一个A对象可以指向它,所以我们打破了无限循环。

答案 1 :(得分:0)

考虑到你要求类之间的引用,可能你来自Java,C#或类似的背景,其中只能将对象的引用放在其他对象中。

在C ++中没有这样的限制:允许您将一个对象的内容完全嵌套在另一个对象中。但要使其工作,您必须事先提供嵌套对象的定义。 C ++需要此定义才能计算外部对象的大小和布局。为了摆脱这种嵌套,你不需要在外部对象中放置对象本身,而是放置pointerreference

话虽如此,

// 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.x a.pb    b.y b.pa    PA2

这在Java / C#中是不可能的。