一、問題描述
現在有兩個類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> |