亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Delphi > 正文

DELPHI的原子世界(1)

2019-11-18 18:51:42
字體:
來源:轉載
供稿:網友

在使用DELPHI開發軟件的過程中,我們就像草原上一群快樂牛羊,無憂無慮地享受著Object Pascal語言為我們帶來的陽光和各種VCL控件提供的豐富的水草。抬頭望望無邊無際蔚藍的天空,低頭品嘗大地上茂密的青草,誰會去想宇宙有多大,比分子和原子更小的東西是什么?那是哲學家的事。而哲學家此時正坐在高高的山頂上,仰望宇宙星云變換,凝視地上小蟲的爬行,驀然回頭,對我們這群吃草的牛羊點頭微笑。隨手扯起一根小草,輕輕地含在嘴里,閉上眼睛細細品嘗,不知道這根青草在哲學家的嘴里是什么味道?只是,他的臉上一直帶著滿意的微笑。
    認識和了解DELPHI微觀的原子世界,可以使我們徹底理解DELPHI的宏觀應用程序結構,從而在更廣闊的思想空間中開發我們的軟件。這就好像,牛頓發現了宏觀物體的運動,卻因為搞不清物體為什么會這樣運動而苦惱,相反,愛因斯坦卻在基本粒子規律和宏觀物體運動之間體驗著相對論的快樂生活!

第一節  TObject原子
    TObject是什么?
    是Object Pascal語言體系結構的基本核心,也是各種VCL控件的起源。我們可以認為,TObject是構成DELPHI應用程序的原子之一,當然,他們又是由基本Pascal語法元素等更細微的粒子構成。
    說TObject是DELPHI程序的原子,是因為TObject是DELPHI編譯器內部支持的。所有的對象類都是從TObject派生的,即使你并未指定TObject為祖先類。TObject被定義在System單元,它是系統的一部分。在System.pas單元的開頭,有這樣的注釋文本:
    { PRedefined constants, types, procedures, }
    { and functions (such as True, Integer, or }
    { Writeln) do not have actual declarations.}
    { Instead they are built into the compiler }
    { and are treated as if they were declared }
    { at the beginning of the System unit.    }
    它的意思說,這一單元包含預定義的常量、類型、過程和函數(諸如:Ture、Integer或Writeln),它們并沒有實際的聲明,而是編譯器內置的,并在編譯的開始就被認為是已經聲明的定義。你可以將Classes.pas或Windows.pas等其他源程序文件加入你的項目文件中進行編譯和調試其源代碼,但你絕對無法將System.pas源程序文件加入到你的項目文件中進行編譯!DELPHI將報告重復定義System的編譯錯誤!
    因此,TObject是編譯器內部提供的定義,對于我們使用DELPHI開發程序的人來說,TObject是原子性的東西。
    TObject在System單元中的定義是這樣的:
  TObject = class
    constructor Create;
    procedure Free;
    class function InitInstance(Instance: Pointer): TObject;
    procedure CleanupInstance;
    function ClassType: TClass;
    class function ClassName: ShortString;
    class function ClassNameIs(const Name: string): Boolean;
    class function ClassParent: TClass;
    class function ClassInfo: Pointer;
    class function InstanceSize: Longint;
    class function InheritsFrom(AClass: TClass): Boolean;
    class function MethodAddress(const Name: ShortString): Pointer;
    class function MethodName(Address: Pointer): ShortString;
    function FieldAddress(const Name: ShortString): Pointer;
    function GetInterface(const IID: TGUID; out Obj): Boolean;
    class function GetInterfaceEntry(const IID: TGUID): PInterfaceEntry;
    class function GetInterfaceTable: PInterfaceTable;
    function SafeCallException(ExceptObject: TObject;
      ExceptAddr: Pointer): HResult; virtual;
    procedure AfterConstruction; virtual;
    procedure BeforeDestruction; virtual;
    procedure Dispatch(var Message); virtual;
    procedure DefaultHandler(var Message); virtual;
    class function NewInstance: TObject; virtual;
    procedure FreeInstance; virtual;
    destructor Destroy; virtual;
  end;

    下面,我們將逐步敲開TObject原子的大門,看看里面到底是什么結構。

    我們知道,TObject是所有對象的基本類,那么,一個對象到底是什么?
  DELPHI中的任何對象都是一個指針,這個指針指明該對象在內存中所占據的一塊空間!雖然,對象是一個指針,可是我們引用對象的成員時卻不用寫成這樣的代碼MyObject^.GetName,而只能寫成MyObject.GetName,這是Object Pascal語言擴充的語法,是由編譯器支持的。使用C++ Builder的朋友就很清楚對象與指針的關系,因為在C++ Builder的對象都要定義為指針。對象指針指向的地方就是對象存儲數據的對象空間,我們來分析一下對象指針指向的內存空間的數據結構。
    對象空間的頭4個字節是指向該對象類的虛方法地址表(VMT ?C Vritual Method Table)。接下來的空間就是存儲對象本身成員數據的空間,并按從該對象最原始祖先類的數據成員到該對象類的數據成員的總順序,和每一級類中數據成員的定義順序存儲。
    類的虛方法地址表(VMT)保存從該類的原始祖先類派生到該類的所有類的虛方法的過程地址。類的虛方法,就是用保留字vritual聲明的方法,虛方法是實現對象多態性的基本機制。雖然,用保留字dynamic聲明的動態方法也可實現對象的多態性,但這樣的方法不保存在虛方法地址表(VMT)中,它只是Object Pascal提供的另一種可節約類存儲空間的多態實現機制,但卻是以犧牲調用速度為代價的。
    即使,我們自己并未定義任何類的虛方法,但該類的對象仍然存在指向虛方法地址表的指針,只是地址項的長度為零??墒?,在TObject中定義的那些虛方法,如Destroy、FreeInstance等等,又存儲在什么地方呢?原來,他們的方法地址存儲在相對VMT指針負方向偏移的空間中。其實,在VMT表的負方向偏移76個字節的數據空間是對象類的系統數據結構,這些數據結構是與編譯器相關的,并且在將來的DELPHI版本中有可能被改變。
    因此,你可以認為,VMT是一個從負偏移地址空間開始的數據結構,負偏移數據區是VMT的系統數據區,VMT的正偏移數據是用戶數據區(自定義的虛方法地址表)。TObject中定義的有關類信息或對象運行時刻信息的函數和過程,一般都與VMT的系統數據有關。
    一個VMT數據就代表一個類,其實VMT就是類!在Object Pascal中我們用TObject、TComponent等等標識符表示類,它們在DELPHI的內部實現為各自的VMT數據。而用class of保留字定義的類的類型,實際就是指向相關VMT數據的指針。
    對我們的應用程序來說,VMT數據是靜態的數據,當編譯器編譯完成我們的應用程序之后,這些數據信息已經確定并已初始化。我們編寫的程序語句可訪問VMT相關的信息,獲得諸如對象的尺寸、類名或運行時刻的屬性資料等等信息,或者調用虛方法或讀取方法的名稱與地址等等操作。
    當一個對象產生時,系統會為該對象分配一塊內存空間,并將該對象與相關的類聯系起來,于是,在為對象分配的數據空間中的頭4個字節,就成為指向類VMT數據的指針。
    我們再來看看對象是怎樣誕生和滅亡的??粗胰龤q的兒子在草地上活蹦亂跳,正是由于親眼目睹過生命的誕生過程,我才能真真體會到生命的意義和偉大。也只有那些經歷過死別的人,才會更加理解和珍惜生命。那么,就讓我們理解一下對象的產生和消亡的過程吧!
    我們都知道,用下面的語句可以構造一個最簡單對象:
      AnObject := TObject.Create;
    編譯器將其編譯實現為:
    用TObject對應的VMT為依據,調用TObject的Create構造函數。而在Create構造函數調用了系統的ClassCreate過程,系統的ClassCreate過程又通過存儲在類VMT調用NewInstance虛方法。調用NewInstance方法的目的是要建立對象的實例空間,因為我們沒有重載該方法,所以,它就是TObject類的NewInstance。TObjec類的NewInstance方法將根據編譯器在VMT表中初始化的對象實例尺寸(InstanceSize),調用GetMem過程為該對象分配內存,然后調用InitInstance方法將分配的空間初始化。InitInstance方法首先將對象空間的頭4個字節初始化為指向對象類對應VMT的指針,然后將其余的空間清零。建立對象實例之后,還調用了一個虛方法AfterConstruction。最后,將對象實例數據的地址指針保存到AnObject變量中,這樣,AnObject對象就誕生了。
    同樣,用下面的語句可以消滅一個對象:
      AnObject.Destroy;
    TObject的析構函數Destroy被聲明為虛方法,它也是系統固有的虛方法之一。Destory方法首先調用了BeforeDestruction虛方法,然后調用系統的ClassDestroy過程。ClassDestory過程又通過類VMT調用FreeInstance虛方法,由FreeInstance方法調用FreeMem過程釋放對象的內存空間。就這樣,一個對象就在系統中消失。
    對象的析構過程比對象的構造過程簡單,就好像生命的誕生是一個漫長的孕育過程,而死亡卻相對的短暫,這似乎是一種必然的規律。
在對象的構造和析構過程中,調用了NewInstance和FreeInstance兩個虛函數,來創建和釋放對象實例的內存空間。之所以將這兩個函數聲明為虛函數,是為了能讓用戶在編寫需要用戶自己管理內存的特殊對象類時(如在一些特殊的工業控制程序中),有擴展的空間。
    而將AfterConstruction和BeforeDestruction聲明為虛函數,也是為了將來派生的類在產生對象之后,有機會讓新誕生的對象呼吸第一口新鮮空氣,而在對象消亡之前可以允許對象完成善后事宜,這都是合情合理的事。其實,TForm對象和TDataModule對象的OnCreate事件和OnDestroy事件,就是在TForm和TDataModule重載的這兩個虛函數過程分別觸發的。
此外,TObjec還提供了一個Free方法,它不是虛方法,它是為了那些搞不清對象是否為空(nil)的情況下能安全釋放對象而專門提供的。其實,搞不清對象是否為空,本身就有程序邏輯不清晰的問題。不過,任何人都不是完美的,都可能犯錯,使用Free能避免偶然的錯誤也是件好事。然而,編寫正確的程序不能一味依靠這樣的解決方法,還是應該以保證程序的邏輯正確性為編程的第一目標!
    有興趣的朋友可以讀一讀System單元的原代碼,其中,大量的代碼是用匯編語言書寫的。細心的朋友可以發現,TObject的構造函數Create和析構函數Destory竟然沒有寫任何代碼,其實,在調試狀態下通過Debug的CPU窗口,可清楚地反映出Create和Destory的匯編代碼。因為,締造DELPHI的大師門不想將過多復雜的東西提供給用戶,他們希望用戶在簡單的概念上編寫應用程序,將復雜的工作隱藏在系統的內部由他們承擔。所以,在發布System.pas單元時特別將這兩個函數的代碼去掉,讓用戶認為TObject是萬物之源,用戶派生的類完全從虛無中開始,這本身并沒有錯。雖然,閱讀DELPHI的這些最本質的代碼需要少量的匯編語言知識,但閱讀這樣的代碼,可以讓我們更深刻認識DELPHI世界的起源和發展的基本規律。即使看不太懂,能起碼了解一些基本東西,對我們編寫DELPHI程序也是大有幫助。

第二節  TClass原子
    在System.pas單元中,TClass是這樣定義的:
      TClass = class of TObject;
    它的意思是說,TClass是TObject的類。因為TObject本身就是一個類,所以TClass就是所謂的類的類。
    從概念上說,TClass是類的類型,即,類之類。但是,我們知道DELPHI的一個類,代表著一項VMT數據。因此,類之類可以認為是為VMT數據項定義的類型,其實,它就是一個指向VMT數據的指針類型!
在以前傳統的C++語言中,是不能定義類的類型的。對象一旦編譯就固定下來,類的結構信息已經轉化為絕對的機器代碼,在內存中將不存在完整的類信息。一些較高級的面向對象語言才可支持對類信息的動態訪問和調用,但往往需要一套復雜的內部解釋機制和較多的系統資源。而DELPHI的Object Pascal語言吸收了一些高級面向對象語言的優秀特征,又保留可將程序直接編譯成機器代碼的傳統優點,比較完美地解決了高級功能與程序效率的問題。
    正是由于DELPHI在應用程序中保留了完整的類信息,才能提供諸如as和is等在運行時刻轉換和判別類的高級面向對象功能,而類的VMT數據在其中起了關鍵性的核心作用。有興趣的朋友可以讀一讀System單元的AsClass和IsClass兩個匯編過程,他們是as和is操作符的實現代碼,以加深對類和VMT數據的理解。

    ......
    后面的內容還有對虛構造函數的理解,Interface的實現機制和異常處理的實現機制,等等DLPHI的基本原理。希望五一之后能寫完,再貢獻給大家。 


上一篇:Delphi中RichEdit的奧妙

下一篇:DELPHI的原子世界(2)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人午夜两性视频| 亚洲一区国产精品| 欧美精品免费在线观看| 亚洲激情在线观看视频免费| 日韩av片永久免费网站| 欧美性xxxx极品hd欧美风情| 国内精品中文字幕| 51午夜精品视频| 国产精品久久久久久一区二区| 26uuu另类亚洲欧美日本老年| 国产日韩欧美视频| 亚洲人成在线观看网站高清| 日本久久中文字幕| 在线国产精品播放| 国产精选久久久久久| 国产午夜精品麻豆| 国产亚洲人成网站在线观看| 精品国产精品自拍| 日韩av网站电影| 久久91精品国产91久久久| 欧美性受xxx| 国产一区二区av| 欧美激情久久久久久| www.久久久久| 精品自拍视频在线观看| 美女久久久久久久| 欧美午夜精品久久久久久浪潮| 视频直播国产精品| 欧美午夜片欧美片在线观看| 国产成人综合亚洲| 日韩欧美一区二区在线| 精品久久久久久中文字幕一区奶水| 日韩最新中文字幕电影免费看| 日韩欧美精品中文字幕| 欧美黑人一级爽快片淫片高清| 97香蕉久久超级碰碰高清版| 亚洲免费视频网站| 欧美在线播放视频| 欧美成人第一页| 日韩av理论片| 欧美在线影院在线视频| 国产免费一区二区三区在线观看| 成人国产精品色哟哟| 另类天堂视频在线观看| 欧美性xxxxxxx| 日本最新高清不卡中文字幕| 成人精品久久久| 久久伊人色综合| 久久精品久久精品亚洲人| 国产激情综合五月久久| 91色在线视频| 国产精自产拍久久久久久| 在线播放精品一区二区三区| 一区二区国产精品视频| 91精品视频免费| 这里只有精品在线播放| 精品福利免费观看| 国产精品十八以下禁看| 一个人www欧美| 91日本视频在线| 97在线免费视频| 欧美视频不卡中文| 欧美高清理论片| 91成人精品网站| 成人av资源在线播放| 538国产精品一区二区免费视频| 国产精品久久久久一区二区| 欧美日韩福利在线观看| 欧美插天视频在线播放| 久久亚洲私人国产精品va| 97精品国产97久久久久久| 亚洲精品国产综合久久| 色婷婷成人综合| 国产精品美乳一区二区免费| 久久在线免费视频| 最近2019中文字幕大全第二页| 亚洲黄色在线看| 精品视频在线播放免| www.亚洲一区| 欧美国产日韩中文字幕在线| 欧美日韩第一页| 91色视频在线观看| 日韩欧美极品在线观看| 久久精品中文字幕| 久久久久国色av免费观看性色| 国产视频久久久| 97久久精品人搡人人玩| 欧美激情一级二级| 亚洲国产一区自拍| 国产精品久久久久久久久久久久久| 日韩精品亚洲视频| 欧美精品少妇videofree| 国外成人在线直播| 国产日韩精品一区二区| 国产精品www| 欧美在线国产精品| 在线播放日韩精品| 亚洲一区二区三区在线免费观看| 亚洲男人的天堂网站| 精品久久久久久久久久久久| 中文字幕日韩av电影| 亚洲欧洲国产精品| 亚洲欧美在线看| 国产精品久久久久久久久久| 一区二区三区国产在线观看| 亚洲精品网址在线观看| 国产视频精品久久久| 美女精品视频一区| 精品二区三区线观看| 亚洲电影天堂av| 亚洲人精品午夜在线观看| 91chinesevideo永久地址| 懂色av中文一区二区三区天美| 91精品久久久久久久久不口人| 中文字幕国产日韩| 欧美性理论片在线观看片免费| 欧美极品少妇xxxxⅹ裸体艺术| 国产精品美女久久久久av超清| 欧美午夜精品在线| 不卡中文字幕av| 欧美国产视频一区二区| 中文字幕久热精品视频在线| 亚洲国内高清视频| 国产一区二区视频在线观看| 一区二区三区黄色| 欧美激情一区二区三区久久久| 青青草一区二区| 日韩av综合网站| 日本国产精品视频| 日韩av手机在线看| 精品人伦一区二区三区蜜桃网站| 久久国内精品一国内精品| 日本三级韩国三级久久| 麻豆国产精品va在线观看不卡| 国产一区二区久久精品| 国产精品爽黄69| 91精品国产一区| 欧美日韩性生活视频| 欧美国产精品人人做人人爱| 日韩一级裸体免费视频| 午夜精品一区二区三区在线视| 欧美在线性爱视频| 亚洲v日韩v综合v精品v| 国产精品美女无圣光视频| www国产精品com| 一本色道久久88综合亚洲精品ⅰ| 国产精品久久久久久久久久三级| 国产日本欧美一区二区三区| 国产精品老牛影院在线观看| 精品国产一区二区三区久久| 精品日韩美女的视频高清| 精品久久久91| 日韩小视频在线观看| 91国自产精品中文字幕亚洲| 夜色77av精品影院| 久久久久久久久亚洲| 成人亚洲欧美一区二区三区| 91精品免费久久久久久久久| 亚洲激情视频网| 国产精品久久久久高潮| 国产www精品| 日韩va亚洲va欧洲va国产| 亚洲欧美国产一本综合首页| 一区二区亚洲精品国产|