Delphi和C++的文法區別

來源:互聯網
上載者:User
一、Delphi永遠沒辦法在棧上建立一個對象

下面是一段常見的的Delphi代碼,在過程的開頭聲明本過程所需要的全部局部變數:

procedure Foo;
var
obj: TObject; //這句容易被C++程式員誤會。
begin
...
end;

C++程式員會以為obj這個變數就是TObject對象執行個體本身,會以為這一句是在棧上聲明並構造了TObject類的一個對象執行個體,他們會與下面的C++代碼混淆:

void Foo() {     CObject obj; //這一句的確在棧上構造了CObject類的
... //一個對象執行個體,並且將在離開Foo函數時自動析構它
}

牢記一點,在Delphi裡,永遠不可能在棧上構造一個對象,也永遠不可能對一個對象進行值傳遞,程式員能看到的是“指向對象執行個體的指標”,簡單地說“一切皆指標”,上例中obj其實就是一個“TObject類型的指標”,當它在棧上被聲明的時候,它的值不可知(與C++一樣),也沒有任何對象被構造出來。上述代碼翻譯成C++,基本上就是:

void Foo() {
CObject * obj; // 聲明一個CObject類型的指標
// 但沒有任何對象被構造或與之關聯
...
}

作為一個佐證,在Delphi裡,sizeof(TObject), sizeof(Self), sizeof(obj) 結果都是4,即一個32位指標的大小。

二、Delphi的建構函式更象是個類方法(靜態成員函數)

由於Delphi不允許在棧上構造對象,那麼對象執行個體就只能建立在堆上,Delphi沒有new關鍵字(倒有一個名為New的procedure),而是用一種有別於C++的文法來(在堆上)構造對象:

procedure Foo;
var
obj: TObject; //obj本質上只是一個TObject類型的指標
begin
obj := TObject.Create; //在堆上構造一個TObject對象執行個體並將其地址賦值給obj
obj.Free; //令obj指向的對象析構
end;

與C++一樣,在堆上構造的函數不會在離開範圍的時候被自動析構,所以在離開Foo這個過程之些,要調用TObject的Free方法來析構它。Free方法會調用Destroy解構函式,只不過在調用Destroy之前會判斷Self是否為空白,如果為空白就直接返回。Delphi裡的Self,就是C++裡的this。

Delphi是單根繼承,所有類都從TObject派生而來,而所有類的建構函式一定名為Create,而解構函式一定名為Destroy,當然,解構函式肯定是虛函數。

從聲明的形式上看,Create方法象是一個成員函數,但從使用上看,它更象一個類方法(C++裡叫靜態成員函數),因為調用它的時候,限定名不是對象,而是類名(Txxxxx.Create)。

三、Delphi的解構函式中可以調用純虛方法

由於在Delphi的解構函式Destroy裡,可以調用任何純虛函數(在C++裡這一點是不可想象的),所以可以認為這個時候,虛方法表有一定未被破壞,那麼,如果基類就可以決定析構時一定要調用的函數,哪怕這個函數是個虛函數,甚至純虛函數。

四、Delphi在構造的時候自動將成員變數清零

任何一個Delphi中的類,當它被構造後,它的所有成員變數被清零,布爾型初始為False,字串初始為空白,整型和浮點型初始化為0……而C++沒有這樣的保證

五、Delphi建構函式中拋出異常會自動先調用解構函式

Delphi裡,如果建構函式中拋出了異常,則會自動先執行解構函式,然後再把異常向外拋出;而在C++裡,建構函式中若有異常拋出,則解構函式是不會被調用的。

六、Delphi簡化了COM介面中的AddRef、Release和QueryInterface

C++裡一般用模板對COM介面進行封裝,而在Delphi裡,AddRef、Release以及QueryInterface都被編譯器隱藏掉了,當把一個IUnknown類型的變數(本質上也是一個指標)賦值給另一個變數時,編譯器在背後自動AddRef,當一個IUnknown變數離開範圍的時候(再也沒有人使用它),Release被自動調用,而QueryInterface被抽象為AS運算子:

procedure Foo(const AParam: IUnknown);
var
  bar: IUnknown;
  other: IStream;
begin
  bar := AParam;  //AParam指向的執行個體由於賦值操作被AddRef一次
  other := bar as IStream; //調用了一次QueryInterface,引用計數再次加一
end; //返回時,other和bar都離開範圍,分別被調用Release各一次

C++中用模板(比如_com_ptr)也可以使引用計數自動化,不過QueryInterface就沒那麼方便了 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.