定義
當一個類繼承另一個類時,這個類被稱為導出類,繼承類或子類,另一個類稱父類、基類或超類。例如Turbo Pascal 5.5及以上版本中有如下語句(其中儘管大小寫不敏感,但仍然推薦大小寫交錯以增加程式可讀性):
type
Movement=object
Direction:0..360;{方向}
Speed:0..400;{速度}
SpeedChange:-10..10;{速度改變}
procedure Init;{初始化}
procedure Accelerate;{加速}
procedure Decelerate;{減速}
end;
AirStatus=object(Movement)
Altitude:0..35000;{高度}
AltChange:-100..100;{高度改變}
procedure Init;{初始化}
procedure Ascend;{爬升}
procedure Descend;{下降}
end;
在AirStatus的定義中,由於包含了對Movement的引用,所以除了新定義的數據欄位Altitude,AltChange和方法Ascend,Descend外,AirStatus還繼承了Movement的所有數據和方法。(如Direction,Speed,Accelerate等)
用OOP的術語來說,“Movement”為“祖先”類型,“AirStatus”是其一個“後代”類型。他們的關係叫做“繼承”或“對象繼承”。
導出類的使用方式
導出類的簡單方式
這種方式是比較簡單的,同時也是不建議採用的不合適方式。
只需要在導出類加上__declspec(dllexport),就可以實現導出類。對象空間還是在使用者的模組里,dll只提供類中的函式代碼。不足的地方是:使用者需要知道整個類的實現,包括基類、類中成員對象,也就是說所有跟導出類相關的東西,使用者都要知道。通過Dependency Walker可以看到,這時候的dll導出的是跟類相關的函式:如構造函式、賦值操作符、析構函式、其它函式,這些都是使用者可能會用到的函式。
這種導出類的方式,除了導出的東西太多、使用者對類的實現依賴太多之外,還有其它問題:必須保證使用同一種編譯器。導出類的本質是導出類里的函式,因為語法上直接導出了類,沒有對函式的調用方式、重命名進行設定,導致了產生的dll並不通用。
導出類的較好方式
這種方式是比較合適的,跟com類似。
結構是這樣的:導出類是一個派生類,派生自一個抽象類——都是純虛函式。使用者需要知道這個抽象類的結構。DLL最少只需要提供一個用於獲取類對象指針的接口。使用者跟DLL提供者共用一個抽象類的頭檔案,使用者依賴於DLL的東西很少,只需要知道抽象類的接口,以及獲取對象指針的導出函式,對象記憶體空間的申請是在DLL模組中做的,釋放也在DLL模組中完成,最後記得要調用釋放對象的函式。
這種方式比較好,通用,產生的DLL沒有特定環境限制。藉助了C++類的虛函式。一般都是採用這種方式。除了對DLL導出類有好處外,採用接口跟實現分離,可以使得工程的結構更清晰,使用者只需要知道接口,而不需要知道實現。
總結
導出類是比較簡單的,比較容易混淆的概念上一篇總結已經說完了。本質上來說,跟導出函式沒差別。
使用VS2005自動生成的代碼可以省去很多力氣,比起以前做練習什麼都是自己動手寫方便多了。要注意一下工程的設定,熟悉它們的作用可以加快編程速度。