交叉引用的解決方法——類宣告的應用

發表於2016-12-07

交叉引用的解決方法

什麼是交叉引用?

什麼是交叉引用?一言以蔽之,就是:A類中包含B類的物件,B類中包含A類的物件。

以一場景為例

我們先來看一個場景。假設有一個電子文件(Document)、一個文件下有多個頁(Page),每個頁下有多個文字單元(TextUnit,表示文件內元素的基本單位),一個文件中的所有文字單元物件都有唯一的ID。這樣每建立一個文字單元時都要為其設定一個唯一的ID,我們在Document類中就需要一個生成唯一ID的方法為所有的文字單元建立唯一標識。於是我們就會有下面的類關係設計圖:

這裡寫圖片描述
圖1 :類的關係圖

於是我們想當然的會有這樣的程式碼:

TextUnit.h:

TextUnit.cpp:

Page.h:

Page.cpp:

Document.h:

Document.cpp:

編譯

好,程式碼寫完了,我們對它進行編譯,這時你會發現一堆的錯誤:

1>d:部落格文章c++高階編輯projectscrossreferencecrossreferencedocument.h(6): error C2065: ‘Page’ : undeclared identifier
1>d:部落格文章c++高階編輯projectscrossreferencecrossreferencedocument.h(6): error C2059: syntax error : ‘>’
1>d:部落格文章c++高階編輯projectscrossreferencecrossreferencedocument.h(9): error C2143: syntax error : missing ‘;’ before ‘{’

1>d:部落格文章c++高階編輯projectscrossreferencecrossreferencepage.h(12): error C2061: syntax error : identifier ‘Document’
1>d:部落格文章c++高階編輯projectscrossreferencecrossreferencepage.h(20): error C2143: syntax error : missing ‘;’ before ‘*’
1>d:部落格文章c++高階編輯projectscrossreferencecrossreferencepage.h(20): error C4430: missing type specifier – int assumed. Note: C++ does not support default-int
1>d:部落格文章c++高階編輯projectscrossreferencecrossreferencepage.h(20): error C4430: missing type specifier – int assumed. Note: C++ does not support default-int

原因分析

這是因為
1. C++中,在建立或使用一個類時,這個類必須被定義完整(就是一個完整的型別);
2. 類的定義也可以和函式一樣分成兩步,先宣告後定義。

這種宣告也被稱為前向宣告,在程式中引入名字T,並指明T是一種類型別。此時的T在它被定義之前是不完整的型別(incomplete type),也就是說只知道它是一種類型別,並不知道它有哪些成員,但可定義這個型別(T)的指標和引用。

類的定義:

只有類(T)定義完成,它才是一個完整的型別,才是可見的(才可被建立和使用)。

而我們的程式現在就出現這種很有意思的狀態:在定義Document時,發現Page還沒有定義完整(Document中有Page型別的成員);在定義Page的時候發現Document還沒有定義完整(Page中有Document型別的指標物件)。也就是說Document不知道Page,Page不知道Docunent,這時就像兩隻狗打架,A狗咬著B狗的尾巴,B狗咬著A狗的尾巴。

解決方法

1.在Document.h文字中加入Page類的宣告:calss Page; 把include “Page.h”放到Document.cpp中。
2.Page.h文字中加入Page類的宣告:calss Document; 把include “Document.h”放到Page.h中。

程式碼如下:
Document.h:

Document.cpp:

Page.h:

Page.cpp:

相關文章