以前覺得 class 引用可以代替所有的include。事實當然不是這樣的。
我的文件中類A繼承於類B,我在A的頭文件中,居然寫到class B;結果,你懂得。
下面是轉帖了 ,有三種情況 class引用可以代替include。
在C++中爲類編寫頭文件的時候,總要#include一大堆頭文件。其實其中的大部分都是不需要的。
C++編輯器需要做的事情其實很簡單1:掃描符號2:確定對象的大小。
爲了確定這兩件事情並不一定需要#include你用到的其他類的頭文件。而只需要一個類型申明而已.
1.使用到類型的引用。首先我們知道對象的引用不是對象本身而是類似指針一樣的東西。所以任何類型的對象的引用所佔有的空間都是相同的。所以這裏爲了確定類型對象的大小,並不需要#include所使用到的類型的定義。
舉例如下:
#ifndef SAMPLE_H_
#define SAMPLE_H_
class Sample
{
public:
Sample();
virtual
~Sample();
private :
string& mSampleName;
};
#endif
這段代碼會產生一個編譯錯誤.具體的原因就是找不到string這個類型。那麼如何解決呢?我以前一般都是#include
<string> using namespace
std;其實這裏不需要因爲mSampleName是一個string的引用而已.
只需要前向聲明一下她是一個類型就可以了。
#ifndef SAMPLE_H_
#define SAMPLE_H_
class string;
class Sample
{
public:
Sample();
virtual
~Sample();
private :
string& mSampleName;
};
#endif 注意新添加的那一行,這樣就可以了。
2.使用類型的指針
和上面的例子一樣,指針的大小總是可以確定的。所以也不需要#include頭文件。只需要前向聲明就可以了。
3.在成員函數的參數中使用的類型
無論類型是什麼都只需要使用前向聲明,因爲成員函數幾乎是不佔對象的大小的。
#ifndef SAMPLE_H_
#define SAMPLE_H_
class string;
class IEnvelope;
class Sample
{
public:
Sample();
virtual
~Sample();
public:
IEnvelope
GetEnvelope();
bool
QueryEnvelope(IEnvelope& pEnv);
private :
string& mSampleName;
};
#endif
在寫這段代碼的時候我的project中根本就沒有IEnvelope這個類型。所以其實根本沒有IEnvelope.h可以#include。但是使用前向聲明就可以讓代碼編譯過去。這是因爲成員函數不佔用對象大小的原因。
總之在頭文件裏面如果你認爲即使不能確定所使用到的某個類型的大小還是可以確定當前類型的對象的大小的時候就可以不用#include所使用到的類型的頭文件。只需要前向聲明一下就可以了。前向聲明的作用在於告訴編譯器這個一個在別的地方定義的類型。這樣C++編譯器就能生成正確的符號表了。