類定義與前置宣告

2021-06-06 07:08:59 字數 1396 閱讀 2061

本文要寫的是近期做專案過程中遇到的乙個語法方面的小問題,下文從問題描述,解決思路以及總結這樣的三段式描述來記錄一下,以為備忘。

問題描述很簡單。在實現乙個模組的過程中,在標頭檔案x.h中定義了class b, class b繼承自class a; class a定義在y.h中;為了避免兩個標頭檔案之間不同資料結構定義之間的複雜依賴導致的問題,在標頭檔案x.h中使用了對class a的前置宣告,在原始檔x.cxx中包含了標頭檔案x.h和y.h。

x.cxx:

#include "x.h"

#include "y.h"

use class b;

x.h:

#ifndef x_h_included

#define x_h_included

class a;

class b:public a;

#endif

y.h:

#ifndef y_h_included

#define y_h_included

class a;

#endif

編譯報錯:

x.h:error: invalid use of undefined type struct a

x.h:error: forward declaration of struct a  

解決思路:

我試圖簡單地調換了一下兩個標頭檔案在x.cxx中的包含順序,編譯通過。那麼這裡的問題在哪兒呢?看看將x.h和y.h分別在x.cxx中手動預處理之後會發生什麼樣的劇情。有兩種情形:

1)如果x.h在y.h之前包含,我們得到與處理後的x.cxx的簡要描述如下:

class a;

class b:public a{};

class a{};

use class b;

2)如果y.h在x.h之前包含,我們得到預處理後的x.cxx的簡要描述如下:

class a{};

class a;

class b:public a{};

use class b;

不難看到,編譯報錯的原因在於派生類class b在定義之前編譯器沒有看到基類class a的定義,由於沒有基類的定義,就無法為派生類分配物件。這就是兩個標頭檔案不同的包含順序會導致正確和錯誤兩種編譯結果的本質原因。

總結:從技術層面上,在大型軟體中,模組化程式設計是常用的方式,特別在oo程式中,跨標頭檔案的派生類的定義是比較多的;與此同時,就像我在之前的博文中提到的,在標頭檔案中使用前置宣告是乙個很好的程式設計習慣。兩者結合的時候,我們需要特別注意原始檔中的標頭檔案包含順序,避免出現在定義派生類時沒有基類定義的錯誤。

從解決問題的方法學方面,我的感覺是,解決問題的過程就是乙個先將問題進行簡化和抽象,然後再抽絲剝繭分析問題、按圖索驥找到解決方案的過程,牢牢掌握已知的線索,逐漸還原問題的本質。簡單問題如此,複雜問題更是如此。

C 類宣告 類前置宣告

參考自 關於前置型別宣告的注意點 一 class b class a class b 上述 能夠通過編譯。二 class b class a class b 上述 報錯。error list c2079 a adata uses undefined class b c2027 use of unde...

類的宣告與定義

什麼是類的宣告與定義?一 變數的宣告與定義很容易區分。宣告只是告訴編譯器有這麼乙個變數,但是沒有為它分配空間 定義則是為該變數分配空間。所以變數可以重複宣告,但是不能重複定義。那麼,類的宣告與定義又是什麼呢?之前以為類的宣告就是為類開闢一塊空間 類的定義就是定義乙個物件,也就是為物件分配空間。實際上...

類的宣告與定義

可以宣告乙個類而不定義它。class screen 宣告而未定義 在宣告之後 定義之前,類screen是乙個不完全型別,即已知screen是乙個型別,但不知道包含哪些成員。不完全型別只能以有限的方式使用。不能用來定義該型別的物件,只能用於定義指向該型別的指標及引用,或用於宣告 不能是定義 使用該型別...