VC++開發(fā)中完美解決頭文件相互包含問題的方法解析
所謂超前引用是指一個類型在定義之前就被用來定義變量和聲明函數(shù)。
一般情況下,C/C++要求所有的類型必須在使用前被定義,但是在一些特殊情況下,這種要求無法滿足,例如,在類CMyView中保留了一個非模式對話框?qū)ο笾羔?,該對象用于顯示/修改一些信息。為了實(shí)現(xiàn)對話框"應(yīng)用"按鈕,把對話框做的修改立刻更新到view界面上,為此,需要在對話框類中需要保存view類的指針,這樣定義關(guān)系就變成如下的代碼:
#ifndef __MYVIEW_H__
#define __MYVIEW_H__
//這是view類的頭函數(shù)
#include "MyDialog.h"
class CMyView::public CView
{
protected:
CMyDialog * pDlg;
//這里是其他定義
};
#endif
#ifndef __MYDIALOG_H__
#define __MYDIALOG_H__
//這是對話框類的定義
#include "MyView.h"
class CMyDialog::public CDialog
{
protected:
CMyView * pView;
//其他定義
};
#endif
從編譯器角度看,編譯MyDialog.CPP時,系統(tǒng)首先定義宏__MYDIALOG_H__,然后包含MyView.h,MyView.h中的#include "MyDialog.h"由于__MYDIALOG_H__已經(jīng)定義,所以不再起作用。在CMyView類的聲明中,CMyDialog* pDlg ;就會讓編譯器產(chǎn)生"CMyDialog"類型沒有定義之類的錯誤,編譯MyView.CPP文件出現(xiàn)的錯誤可以類似得到。
一般的情況,類A和類B需要彼此互相引用,這樣必然有一個類會先被定義,而另外一個類后被定義,這樣在先被定義的類引用后被定義的類的時候,就導(dǎo)致了所謂的超前引用。
超前引用導(dǎo)致的錯誤有以下幾種處理辦法:
1) 使用類聲明
在超前引用一個類之前,首先用一個特殊的語句說明該標(biāo)識符是一個類名,即將被超前引用。其使用方法是:
a) 用class ClassB;聲明即將超前引用的類名
b) 定義class ClassA
c) 定義class ClassB;
d) 編制兩個類的實(shí)現(xiàn)代碼。
上述方法適用于所有代碼在同一個文件中,一般情況下,ClassA和ClassB分別有自己的頭文件和cpp文件,這種
方法需要演變成:
a) 分別定義ClassA和ClassB,并在cpp文件中實(shí)現(xiàn)之
b) 在兩個頭文件的開頭分別用class ClassB;和class ClassA;聲明對方
c) 在兩個cpp文件中分別包含另外一個類的頭文件
NOTE:這種方法切記不可使用類名來定義變量和函數(shù)的變量參數(shù),只可用來定義引用或者指針。
2) 使用全局變量
由于全局變量可以避免超前引用,不用贅述。我的習(xí)慣是,把類對象的extern語句加在該類頭文件的最后,大家喜歡怎樣寫那都沒有什么大問題,關(guān)鍵是保證不要在頭文件中胡亂包含。
3) 使用基類指針。
這種方法是在引用超前引用類的地方一律用基類指針。而一般情況下,兩個互相引用的類并不涉及其基類,因此不會造成超前引用。以開始的例子說:在CMyDialog類中用CView*代替CMyView*,在CMyView類中用CDialog*代替CMyDialog*,這樣必然不會造成超前引用。
說明:本文中,為了敘述方便,把class AClass;語句成為類AClass的聲明,把class AClass開始的對AClass的類成員變量、成員函數(shù)原型等的說明稱為類的定義,而把在CPP中的部分稱為類的定義。如果大家對這三個詞有不同的理解,請按照自己的本意把這三個詞換成相應(yīng)的詞來理解。
ps:我是用第一種方法解決問題的。
相關(guān)文章
在1個Matlab m文件中定義多個函數(shù)直接運(yùn)行的操作方法
這篇文章主要介紹了如何在1個Matlab m文件中定義多個函數(shù)直接運(yùn)行,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-12-12C語言實(shí)現(xiàn)班級學(xué)生管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)班級學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11解析VC中創(chuàng)建DLL,導(dǎo)出全局變量,函數(shù)和類的深入分析
本篇文章是對VC中創(chuàng)建DLL,導(dǎo)出全局變量,函數(shù)和類進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C語言數(shù)據(jù)結(jié)構(gòu)系列隊列篇
本章我們將學(xué)習(xí) "隊列" ,首先介紹隊列的概念和結(jié)構(gòu),然后我們將著重講解棧的實(shí)現(xiàn)。我們從零開始寫隊列的接口,并從零開始步步解讀。本章將繼續(xù)鞏固畫思路草圖的能力,只要思路草圖畫好了,就可以很輕松地將其轉(zhuǎn)換成代碼2022-02-02C++使用string的大數(shù)乘法運(yùn)算(3)
這篇文章主要為大家詳細(xì)介紹了C++使用string的大數(shù)乘法運(yùn)算,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-09-09C++實(shí)現(xiàn)廣度優(yōu)先搜索實(shí)例
這篇文章主要介紹了C++實(shí)現(xiàn)廣度優(yōu)先搜索,對于C++程序員來說非常有借鑒價值,需要的朋友可以參考下2014-08-08C/C++ Zlib庫封裝MyZip壓縮類的詳細(xì)過程
在軟件開發(fā)中,文件的壓縮和解壓縮是一項(xiàng)常見的任務(wù),而ZIP是一種被廣泛應(yīng)用的壓縮格式,本文將聚焦于一個簡化的C++實(shí)現(xiàn),通過分析代碼,我們將深入了解其設(shè)計和實(shí)現(xiàn)細(xì)節(jié),感興趣的朋友一起看看吧2023-11-11C++?ncnn模型驗(yàn)證精度實(shí)現(xiàn)代碼
這篇文章主要介紹了C++?ncnn模型驗(yàn)證精度實(shí)現(xiàn)過程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-02-02