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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章