C++中类应当先定义然后才能够使用,但是有时候,两个类存在相互引用的情况,这样无论把哪个类放在前面都不行,这种便叫做循环依赖。
例如
class A
{
public:
void f(B b);
};
class B
{
public:
void g(A a);
};
这里类A的公有成员函数f的形式参数是类B的对象,同时类B的公有成员函数g也以类A的对象为形参。在使用一个类之前,必须首先定义该类,因此无论将哪个类放在前面,都会引起编译错误。解决这种问题的办法就是向前引用声明,在引用未定义的类之前,将该类的名字告诉编译器,使编译器知道那是一个类名。这样,当程序中使用这个类名时,编译器就不会认为是错误,而类的完整定义可以在程序的其他地方。
class B; //向前引用声明
class A
{
public:
void f(B b);
};
class B
{
public:
void g(A a);
};
使用向前引用申明虽然可以解决一些问题,但是它并不是万能的,需要注意的是尽管使用了向前引用声明,但是在提供一个完整的类定义之前,不能定义该类的对象,也不能在内联成员函数中使用该类的对象。如下程序
class Fred;
class Barney
{
Fred x; //错误,类Fred的定义尚不完善
};
class Fred
{
Barney y;
};
对于这段程序,编译器将指出错误。因为类名Fred的前向引用声明只能说明Fred是一个类名,而不能给出该类的完整定义,因此在Barney类中就不能定义Fred的数据成员。因此使两个类以彼此的对象为数据成员是不合法的。
再看下面一段程序:
class Fred;
class Barney
{
public:
void method(){
x.ya(); //错误:Fred类的对象在定义之前被使用
}
private:
Fred &x; //此处是正确的,前向引用声明不可以定义类的对象,但是可以声明Fred类的对象引用或指针
};
class Fred
{
public:
void ya();
private:
Barney &y;
};
如果想使用method函数,那么我们可以将它改为非内联函数,不过要在Fred完整定以后再给出函数定义。
经过上面一些举证,你对前向引用声明有了一定了解吧,这种方法主要用来处理两个类之间互相依赖的时候一些注意点。
注:上面内容摘抄自《C++程序设计第四版》清华大学出版社