所謂超前引用是指乙個型別在定義之前就被用來定義變數和宣告函式。
一般情況下,
c/c++
要求所有的型別必須在使用前被定義,但是在一些特殊情況下,這種要求無法滿足,例如,在類
cmyview
中保留了乙個非模式對話方塊物件指標,該物件用於顯示
/修改一些資訊。為了實現對話方塊"應用
"按鈕,把對話方塊做的修改立刻更新到
view
介面上,為此,需要在對話方塊類中需要儲存
view
類的指標,這樣定義關係就變成如下的**:
#ifndef __myview_h__
#define __myview_h__
//這是
view
類的頭函式
#include "mydialog.h"
class cmyview::public cview
;#endif
#ifndef __mydialog_h__
#define __mydialog_h__
//這是對話方塊類的定義
#include "myview.h"
class cmydialog::public cdialog
;#endif
從編譯器角度看,編譯
mydialog.cpp
時,系統首先定義巨集
__mydialog_h__
,然後包含
myview.h
,myview.h
中的#include "mydialog.h"
由於__mydialog_h__
已經定義,所以不再起作用。在
cmyview
類的宣告中,
cmydialog* pdlg ;
就會讓編譯器產生
"cmydialog"
型別沒有定義之類的錯誤,編譯
myview.cpp
檔案出現的錯誤可以類似得到。
更一般的情況,類a和類
b需要彼此互相引用,這樣必然有乙個類會先被定義,而另外乙個類後被定義,這樣在先被定義的類引用後被定義的類的時候,就導致了所謂的超前引用。
超前引用導致的錯誤有以下幾種處理辦法:
1) 使用類宣告
在超前引用乙個類之前,首先用乙個特殊的語句說明該識別符號是乙個類名,即將被超前引用。其使用方法是:
a)
用class classb
;宣告即將超前引用的類名
b)
定義class classa
c)
定義class classb;
d)
編制兩個類的實現**。
上述方法適用於所有**在同乙個檔案中,一般情況下,
classa
和classb
分別有自己的標頭檔案和
cpp檔案,這種
方法需要演變成:
a) 分別定義
classa
和classb
,並在cpp
檔案中實現之
b) 在兩個標頭檔案的開頭分別用
class classb;
和class classa;
宣告對方
c) 在兩個
cpp檔案中分別包含另外乙個類的標頭檔案
note:
這種方法切記不可使用類名來定義變數和函式的變數引數,只可用來定義引用或者指標。
2) 使用全域性變數
由於全域性變數可以避免超前引用,不用贅述。我的習慣是,把類物件的
extern
語句加在該類標頭檔案的最後,大家喜歡
怎樣寫那都沒有什麼大問題,關鍵是保證不要在標頭檔案中胡亂包含。
3) 使用基類指標。
這種方法是在引用超前引用類的地方一律用基類指標。而一般情況下,兩個互相引用的類並不涉及其基類,因此不會造成
超前引用。以開始的例子說:在
cmydialog
類中用cview*
代替cmyview*
,在cmyview
類中用cdialog*
代替cmydialog*
,這樣必然
不會造成超前引用。
說明:本文中,為了敘述方便,把
class aclass;
語句成為類
aclass
的宣告,把
class aclass
開始的對
aclass
的類成員變數、
成員函式原型等的說明稱為類的定義,而把在
cpp中的部分稱為類的定義。如果大家對這三個詞有不同的理解,請按照自己的本意把這三個詞換成相應的詞來理解。
解決標頭檔案相互包含問題的方法
所謂超前引用是指乙個型別在定義之前就被用來定義變數和宣告函式。一般情況下,c c 要求所有的型別必須在使用前被定義,但是在一些特殊情況下,這種要求無法滿足,例如,在類cmyview中保留了乙個非模式對話方塊物件指標,該物件用於顯示 修改一些資訊。為了實現對話方塊 應用 按鈕,把對話方塊做的修改立刻更...
解決標頭檔案相互包含問題的方法 超前引用
所謂超前引用是指乙個型別在定義之前就被用來定義變數和宣告函式。一般情況下,c c 要求所有的型別必須在使用前被定義,但是在一些特殊情況下,這種要求無法滿足,例如,在類cmyview中保留了乙個非模式對話方塊物件指標,該物件用於顯示 修改一些資訊。為了實現對話方塊 應用 按鈕,把對話方塊做的修改立刻更...
c 標頭檔案相互包含問題
c 中標頭檔案互相包含經常會出現編譯錯誤.示例 如下 h ifndef a h define a h include b.h includeusing namespace std class a endif a h a.cpp include a.h a a a a int a getvala vo...