C++类循环依赖
2013-10-24 10:53
169 查看
最近開始久違的寫C++程式,然後因為物件上的關係,所以某個A類別會擁有B類別,同時B類別會需要知道A類別
為了能夠壤兩個類別都能夠看到,所以依照直覺的想法,會使兩方的標頭檔(Header file)都會Include彼此,但是此時編譯器卻會發生問題,究竟是為什麼呢? 這樣的想法不是很合理嗎?
但其實編譯器在解讀時是會出現問題的,究竟哪裡有問題?
經過朋友的解說後,解決了問題也知道了原因,這邊來介紹一下給需要知道的人。
類別互相引用
有時候在開發物件導向的程式時,免不了因為一些OO關係,需要讓某個A類別會擁有B類別,同時B類別會需要知道A類別:
標頭檔互相引用的錯誤的原因
這邊我們拿A與B類別來解釋,前面提到「A類別會擁有B類別,同時B類別會需要知道A類別」,因為擁有B,所以需要include B,而B因為知道A,貌似直覺的做法B也會include A,此時在編譯的程序就會變成:
A class -> A Include B-> 進入B class -> B include A -> A class
所以會再次去A class的標頭檔(如下程式碼)
A.h
B.h
依照常理來說,一般我們在寫標頭檔時,會使用 #ifndef 、#define、#endif的前置處理指令,確保只會被編譯過一次,之後被include多次時,不會再被編譯:
但是問題卻來,編譯時編譯A檔案,此發實現include B,便跳至B檔案,卻又發現B檔案有include A,再次跳回A檔案時,卻會因為A檔案先前編譯時,因為有加入#ifndef A_H與#define A_H的關係,定義過A_H,便不會再往下編譯A class,因此而又跳回B檔案,造成B檔案不認識A Class而在編譯其出錯。
但是,其實我們的B Class只是知道A(pointer)而已,根本不需要include A.h
解決方式-前置宣告(Forward Declartion)
我們可以透過前至宣告的方式來告訴編譯器「先知道這個class的存在,至於他的定義後面會說明」。
只要不涉及生成或操作的話,前至宣告可以用在指標或參考類別。
然後再.cpp檔實際操作時,在include 類別標頭檔:
A.h
A.cpp
B類別稍微修改一下:
B.h
在cpp檔中,我們在來incldue A.h檔
B.cpp
以上的原因與解決方式,希望可以幫助到遇到此問題的人可以解惑!
為了能夠壤兩個類別都能夠看到,所以依照直覺的想法,會使兩方的標頭檔(Header file)都會Include彼此,但是此時編譯器卻會發生問題,究竟是為什麼呢? 這樣的想法不是很合理嗎?
但其實編譯器在解讀時是會出現問題的,究竟哪裡有問題?
經過朋友的解說後,解決了問題也知道了原因,這邊來介紹一下給需要知道的人。
類別互相引用
有時候在開發物件導向的程式時,免不了因為一些OO關係,需要讓某個A類別會擁有B類別,同時B類別會需要知道A類別:
標頭檔互相引用的錯誤的原因
這邊我們拿A與B類別來解釋,前面提到「A類別會擁有B類別,同時B類別會需要知道A類別」,因為擁有B,所以需要include B,而B因為知道A,貌似直覺的做法B也會include A,此時在編譯的程序就會變成:
A class -> A Include B-> 進入B class -> B include A -> A class
所以會再次去A class的標頭檔(如下程式碼)
A.h
#ifndef A_H #define A_H #include "B.h" class A { public: A(void); ~A(void); private: B b; }; #endif
B.h
#ifndef B_H #define B_H #include "A.h" class B { public: B(void); ~B(void); private: A *a; }; #endif
依照常理來說,一般我們在寫標頭檔時,會使用 #ifndef 、#define、#endif的前置處理指令,確保只會被編譯過一次,之後被include多次時,不會再被編譯:
#ifndef A_H #define A_H class A{ //.... } #endif
但是問題卻來,編譯時編譯A檔案,此發實現include B,便跳至B檔案,卻又發現B檔案有include A,再次跳回A檔案時,卻會因為A檔案先前編譯時,因為有加入#ifndef A_H與#define A_H的關係,定義過A_H,便不會再往下編譯A class,因此而又跳回B檔案,造成B檔案不認識A Class而在編譯其出錯。
但是,其實我們的B Class只是知道A(pointer)而已,根本不需要include A.h
解決方式-前置宣告(Forward Declartion)
我們可以透過前至宣告的方式來告訴編譯器「先知道這個class的存在,至於他的定義後面會說明」。
只要不涉及生成或操作的話,前至宣告可以用在指標或參考類別。
然後再.cpp檔實際操作時,在include 類別標頭檔:
A.h
#ifndef A_H #define A_H #include "B.h" class A { public: A(void); ~A(void); private: B b; }; #endif
A.cpp
#include "A.h" A::A(void) { } A::~A(void) { }
B類別稍微修改一下:
B.h
#ifndef B_H #define B_H class A; class B { public: B(void); ~B(void); private: A *a; }; #endif
在cpp檔中,我們在來incldue A.h檔
B.cpp
#include "B.h" #include "A.h" B::B(void) { } B::~B(void) { }
以上的原因與解決方式,希望可以幫助到遇到此問題的人可以解惑!
相关文章推荐
- (c++)图形2
- c++选择排序法
- 小记:c++ vector 可能占用大量内存
- C++语法一二
- 10.C语言之动态内存分配
- [互联网面试笔试汇总C/C++-21] FIFO 、LRU、LFU的含义、原理和实现-完美世界
- 常见排序算法之-冒泡排序(C++实现)
- c++使用toolsoapkit调用webservice
- 哈希表例子(C语言实现)
- (C++)图形1
- C语言库函数
- C++嵌套类及对外围类成员变量的访问
- typedef struct 用法详解和用法小结
- C++ string 用法详解
- 不用sqrt如何在C语言中开平方
- 浮点数转换成字符串(c语言)
- C++中 static、const和static const 以及它们的初始化
- segment and section for c++ elf
- C语言中const,volatile,restrict的用法总结
- 在VC++中读写INI文件