C 類迴圈依賴

2021-06-18 19:56:47 字數 1810 閱讀 3302

最近開始久違的寫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

#ifndef a_h

#define a_h

#include "b.h"

class a

;#endif

b.h

#ifndef b_h

#define b_h

#include "a.h"

class b

;#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

;#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

;#endif

在cpp檔中,我們在來incldue a.h檔

b.cpp

#include "b.h"

#include "a.h"

b::b(void)

b::~b(void)

以上的原因與解決方式,希望可以幫助到遇到此問題的人可以解惑!

mysql迴圈依賴 spirng迴圈依賴

1.迴圈依賴就是迴圈引用,就是兩個或多個bean相互之間的持有對方,比如circlea引用circleb,circle引用circlec,circlec引用circlea,則它們最終反映了乙個環。此處不是迴圈呼叫,迴圈呼叫是方法之間的迴圈呼叫。迴圈呼叫是無法解決的,除非有終結條件,否則就是死迴圈,最...

Springboot迴圈依賴

如何解決迴圈依賴 最好的方法是重構 進行解耦 從網上搜尋了簡單的方法如下 第一種 專案解決用了這種方式 autowired lazy true private classa classa autowired lazy true private classb classb 在你注入bean時,在互相依...

spring 迴圈依賴

構造器依賴無法解決,使用 快取解決field屬性依賴。a的屬性依賴b,b的屬性依賴a 建立a,設定依賴屬性b,發現b沒有建立,建立b,設定依賴屬性a,先從一級快取singletonobjects中去獲取。如果獲取到就直接return 如果獲取不到或者物件正在建立中 issingletoncurren...