一、Delphi永遠(yuǎn)沒(méi)辦法在棧上創(chuàng)建一個(gè)對(duì)象下面是一段常見(jiàn)的的Delphi代碼,在過(guò)程的開(kāi)頭聲明本過(guò)程所需要的全部局部變量: procedure Foo; C++程序員會(huì)以為obj這個(gè)變量就是TObject對(duì)象實(shí)例本身,會(huì)以為這一句是在棧上聲明并構(gòu)造了TObject類的一個(gè)對(duì)象實(shí)例,他們會(huì)與下面的C++代碼混淆: void Foo() { CObject obj; //這一句的確在棧上構(gòu)造了CObject類的 牢記一點(diǎn),在Delphi里,永遠(yuǎn)不可能在棧上構(gòu)造一個(gè)對(duì)象,也永遠(yuǎn)不可能對(duì)一個(gè)對(duì)象進(jìn)行值傳遞,程序員能看到的是“指向?qū)ο髮?shí)例的指針”,簡(jiǎn)單地說(shuō)“一切皆指針”,上例中obj其實(shí)就是一個(gè)“TObject類型的指針”,當(dāng)它在棧上被聲明的時(shí)候,它的值不可知(與C++一樣),也沒(méi)有任何對(duì)象被構(gòu)造出來(lái)。上述代碼翻譯成C++,基本上就是: void Foo() { 作為一個(gè)佐證,在Delphi里,sizeof(TObject), sizeof(Self), sizeof(obj) 結(jié)果都是4,即一個(gè)32位指針的大小。 二、Delphi的構(gòu)造函數(shù)更象是個(gè)類方法(靜態(tài)成員函數(shù))由于Delphi不允許在棧上構(gòu)造對(duì)象,那么對(duì)象實(shí)例就只能創(chuàng)建在堆上,Delphi沒(méi)有new關(guān)鍵字(倒有一個(gè)名為New的procedure),而是用一種有別于C++的語(yǔ)法來(lái)(在堆上)構(gòu)造對(duì)象: procedure Foo; 與C++一樣,在堆上構(gòu)造的函數(shù)不會(huì)在離開(kāi)作用域的時(shí)候被自動(dòng)析構(gòu),所以在離開(kāi)Foo這個(gè)過(guò)程之些,要調(diào)用TObject的Free方法來(lái)析構(gòu)它。Free方法會(huì)調(diào)用Destroy析構(gòu)函數(shù),只不過(guò)在調(diào)用Destroy之前會(huì)判斷Self是否為空,如果為空就直接返回。Delphi里的Self,就是C++里的this。 Delphi是單根繼承,所有類都從TObject派生而來(lái),而所有類的構(gòu)造函數(shù)一定名為Create,而析構(gòu)函數(shù)一定名為Destroy,當(dāng)然,析構(gòu)函數(shù)肯定是虛函數(shù)。 從聲明的形式上看,Create方法象是一個(gè)成員函數(shù),但從使用上看,它更象一個(gè)類方法(C++里叫靜態(tài)成員函數(shù)),因?yàn)檎{(diào)用它的時(shí)候,限定名不是對(duì)象,而是類名(Txxxxx.Create)。 三、Delphi的析構(gòu)函數(shù)中可以調(diào)用純虛方法由于在Delphi的析構(gòu)函數(shù)Destroy里,可以調(diào)用任何純虛函數(shù)(在C++里這一點(diǎn)是不可想象的),所以可以認(rèn)為這個(gè)時(shí)候,虛方法表有一定未被破壞,那么,如果基類就可以決定析構(gòu)時(shí)一定要調(diào)用的函數(shù),哪怕這個(gè)函數(shù)是個(gè)虛函數(shù),甚至純虛函數(shù)。 四、Delphi在構(gòu)造的時(shí)候自動(dòng)將成員變量清零任何一個(gè)Delphi中的類,當(dāng)它被構(gòu)造后,它的所有成員變量被清零,布爾型初始為False,字符串初始為空,整型和浮點(diǎn)型初始化為0……而C++沒(méi)有這樣的保證 五、Delphi構(gòu)造函數(shù)中拋出異常會(huì)自動(dòng)先調(diào)用析構(gòu)函數(shù)Delphi里,如果構(gòu)造函數(shù)中拋出了異常,則會(huì)自動(dòng)先執(zhí)行析構(gòu)函數(shù),然后再把異常向外拋出;而在C++里,構(gòu)造函數(shù)中若有異常拋出,則析構(gòu)函數(shù)是不會(huì)被調(diào)用的。 六、Delphi簡(jiǎn)化了COM接口中的AddRef、Release和QueryInterfaceC++里一般用模板對(duì)COM接口進(jìn)行封裝,而在Delphi里,AddRef、Release以及QueryInterface都被編譯器隱藏掉了,當(dāng)把一個(gè)IUnknown類型的變量(本質(zhì)上也是一個(gè)指針)賦值給另一個(gè)變量時(shí),編譯器在背后自動(dòng)AddRef,當(dāng)一個(gè)IUnknown變量離開(kāi)作用域的時(shí)候(再也沒(méi)有人使用它),Release被自動(dòng)調(diào)用,而QueryInterface被抽象為AS運(yùn)算符: procedure Foo(const AParam: IUnknown); C++中用模板(比如_com_ptr)也可以使引用計(jì)數(shù)自動(dòng)化,不過(guò)QueryInterface就沒(méi)那么方便了。 http://www.cnblogs.com/sideandside/archive/2007/04/26/727863.html |
|