C++中两个类互相引用的解决方法

一、问题描述

现在有两个类A和B需要定义,定义A的时候需要用到B,定义B的时候需要用到A。

二、分析

A和B的定义和调用都放在一个文件中肯定是不可以的,这样就会造成两个循环调用的死循环。

根本原因是:定义A的时候,A的里面有B,所以就需要去查看B的占空间大小,但是查看的时候又发现需要知道A的占空间大小,造成死循环。

解决方法:

(1)写两个头文件A.h和B.h分别用于声明类A和B;

(2)写两个.cpp文件分别用于定义类A和B;

(3)在A的头文件中导入B的头文件;

(4)在B的头文件中不导入A的头文件,但是用extern 的方式声明类A,并且,在B中使用A的时候要用指针的形式。

原理:在B中用指针调用A,那么在A需要知道B占空间大小的时候,就会去找到B的定义文件,虽然B的定义文件中并没有导入A的头文件,不知道A的占空间大小,但是由于在B中调用A的时候用的指针形式,B只知道指针占4个字节就可以,不需要知道A真正占空间大小,也就是说,A也是知道B的占空间大小的。

三、C++示例

A的头文件A.h:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef _A
#define _A
<strong>#include "B.h" //A的头文件导入了B的头文件</strong>
//extern class B;
 
class A
{
private :
     int a;
     B objectb; //A的头文件导入了B的头文件,在调用B的时候就可以不用指针
 
public :
     A();
     int geta();
     void handle();
};
 
#endif _A


B的头文件B.h:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef _B
#define _B
 
<strong> //#include "A.h"//B的头文件没有导入A的头文件,需要有三个地方需要注意!
extern class A; //注意1:需要用extern声明A</strong>
 
class B
{
private :
     int b;
     A* objecta; //注意2:调用A的时候需要用指针
public :
     B();
     int getb();
     void handle();
};
 
#endif _B


A的定义文件A.cpp:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
<strong>#include "A.h" </strong>
 
using namespace std;
 
A::A()
{
     this ->a= 100 ;
}
 
int A::geta()
{
     return a;
}
 
void A::handle()
{
     cout<< "in A , objectb.b=" <<objectb.getb()<<endl; }= "" <= "" pre= "" ><br>
<br>
<p></p>
<p><strong>B的定义文件B.cpp:</strong></p>
<p></p>
<pre class = "brush:java;" >#include <iostream>
<strong>#include "B.h"
#include "A.h" //注意3:在B.cpp里面导入A的头文件</strong>
 
using namespace std;
 
B::B()
{
     this ->b= 200 ;
}
 
int B::getb()
{
     return b;
}
 
void B::handle()
{
     objecta= new A();
     cout<< "in B , objecta->a=" <<objecta->geta()<<endl; }= "" <= "" pre= "" ><br>
<br>
<p></p>
<p><strong>main.cpp:</strong></p>
<p></p>
<pre class = "brush:java;" >#include <iostream>
#include <cstdlib>
<strong>#include "A.h"
//#include "B.h" //因为A.h里面已经包含B.h,所以在此不需要导入B.h了。</strong>
 
using namespace std;
 
void main()
{
     A a;
     a.handle();
     B b;
     b.handle();
 
     system( "pause" );
}</cstdlib></iostream></pre><br>
运行结果:
<p></p>
<p><img src= "http://img.2cto.com/Collfiles/20141118/20141118082403328.png" alt= "" style= "width: 270px; height: 89px;" ><br>
</p>
<p><strong>四、注意</strong></p>
<p><strong>下面情况编译不能通过:</strong></p>
<p><strong>A.h中包含B.h且B.h中包含A.h</strong></p>
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值