前向聲明&include區別


下面主要介紹了前向聲明概念、用法以及和#include區別

前向聲明概念(forward declaration)

在程序中引入了類類型的B.在聲明之后,定義之前,類B是一個不完全類型(incompete type),即已知B是一個類型,但不知道包含哪些成員.不完全類型只能以有限方式使用,不能定義該類型的對象,不完全類型只能用於定義指向該類型的指針及引用,或者用於聲明(而不是定義)使用該類型作為形參類型或返回類型的函數.

前向聲明應用場景

當你需要定義兩個類或者結構,例如A和B,而這兩個類需要互相引用,這時候在定義A的時候,B還沒有定義,那怎么引用它呢,這時候就需要前向聲明(forward declaration)了,前向聲明格式如下: class B;當你在定義類A之前聲明了B,那么就會在程序中引入了類類型的B,編譯器知道你會在后面的某個地方定義類B,所以允許你在類A中引用類B。但是,在聲明之后,定義之前,類B是一個不完全類型(incompete type),即已知B是一個類型,但不知道這個類型的一些性質(比如包含哪些成員和操作)。

前向聲明的使用限制:(就拿上面聲明B類說明)

1.不恩能夠定義B類的對象;

2.可以用於定義只想這個類型的指針或者引用;

3.用於聲明使用該類型作為形參或者返回類型的函數;

除了上面的限制,我們可以用它做些什么事情嗎?

在C++中,如果要編寫一個新類的頭文件,一般是要#include一堆依賴的頭文件,但利用前向聲明和c++編譯器的特性,可以減少這里的工作量。

因為c++編譯器做的事情主要是:1.掃描符號;2.確定對象大小。利用這個特性,當我們編寫一個新類的頭文件時,就可以用前向聲明,減少大量的#include,減少編譯的

工作量。

例如:

1.B類用到A類,操作如下,就不需要加A.h了,減少編譯工作量

 

   1:  
   2: //B.h
   3: class A;//調用類A,前向聲明
   4: class 
   5: B
   6: {
   7: private:
   8: A *a; //聲明指針
   9: };

2.在聲明成員函數的形參或者返回類型時,也可以用前向聲明

即使我們沒有定義一個foo類,也可以用,因為成員函數不占類對象的大小,編譯器可以確定對象大小,前向聲明的作用在於告訴編譯器這個一個在別的地方定義的類型。這樣編譯器就能生成正確的符號表了。

 

   1:  
   2: //Sample.h
   3: class foo;
   4: class 
   5: Sample
   6: {
   7: private:
   8: foo foo_test(foo &);
   9: };

常犯錯誤:

 

   1:  
   2: #ifndef RESOURCE_H
   3: #define RESOURCE_H
   4: class 
   5: mybitmap;
   6: class 
   7: resource
   8: {
   9: public:
  10: resource();
  11: ~resource();
  12: private:
  13: mybitmap* 
  14: m_pBitmap;
  15: };
  16: #endif
  17: resource::~resource()
  18: {
  19: if ( 
  20: NULL != m_pBitmap )
  21: {
  22: delete m_pBitmap;
  23: }
  24: }

程序編譯時,會有一個警告,deletion of pointer to incomplete type 'mybitmap'; no destructor called(沒有實踐)

原因就在於#include和class的區別:class如上面所說,而#include是包括一個類的所有定義、成員和方法等信息。

class A 聲明僅僅告訴程序有這樣一個類,你可以在這里聲明類A的一個指針,但是此處並不能獲得類A的具體信息,如果定義類A的一個指針是可以的,但定義一個類A的對象,則程序是錯誤的,因為不知道A的具體信息,故無法生成一個對象。原因是程序中用class聲明的mybitmap類,在執行delete m_pBitmap時,因為它不知道mybitmap類的具體信息,所以無法調用它的析構函數,故內存並沒有釋放,造成內存泄漏。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM