两个类互相引用如

#include "b.h"

class A
{
public:
A();
void get_data();
void print_b();
private:
B b;
int sum;
}


---------------------b.h
#include "a.h"
class B
{
public:
B();
int get_data();
void print_A();
private:
A a;
int sum;
}

可以看看上面的过程。加入首先发现a.h,然后根据a.h把b.h拖进来,然后b.h又把a.h拖进来,此时a.h包含a.h和b.h的内容,也就是说b.h定义了两次,因此会报错。

我们可以使用声明提前的方法解决这个问题

#ifndef _A_H
#define _A_H
#include "b.h"

class A
{
public:
A();
void get_data();
void print_b();
private:
B b;
int sum;
}
#endif

---------------------b.h
#ifndef _B_H
#define _B_H

class A;//只是声明没有定义,因此只能使用指针。因为如果是一个完整的类的话需要知道大小

class B
{
public:
B();
~B();
int get_data();
void print_a();
private:
A* a;//使用指针
int sum;
}
#endef


---------------------a.cpp
#include "a.h"
A::A()
{
b = B();
sum = 0;
}

void A::print_b()
{
cout << b.get_data() << endl;
}

int get_data(){ return sum;}

--------------------b.cpp
#include "a.h"
/*
这是必须是include a,因为开始只定义了class A这一个符号,里面有什么函数我们都不知道,通过include a.h我们才知道A的函数
并且include a.h的同时也include b.h,因为a.h中有include b.h
*/
B::B()
{
a = new A();
sum = 0;
}

void B::print_a()
{
cout << a->get_data() << endl;
}

int B::get_data()
{
return sum;
}

实际上这只是一种权宜之计,出现循环定义本身就代表了代码写的有问题,他容易带来一些不易察觉的问题。

例如
B中引用了A,并且A使用new新建了若干个b的变量。然后在另一个类中A在一个list中,这时我们可能发现过一会B使用A会报错。

这是因为list中的变量经常创建和销毁,销毁时会执行拷贝。但是创建了新的A后B中A的指针还是指向原来被销毁的A,便会出现段错误