c++改Java代碼的體悟

對於匿名對象的使用
c++的匿名對象創建非常簡單,只需要類名+參數就可以,但Java則需要嚴格按照new的方式,去new一個匿名對象創建。

set(Data(1,1,1))//c++
set(new Data(1,1,1))//java

final和const關鍵字
final和const在修飾變量時用法基本相同,都表示不可修改的。但是兩者在修飾方法時卻有很大差別。c++中const修飾一個方法的含義是方法中的量不可以被修改,而Java中final修飾一個方法則是使一個方法在繼承時不可被修改。

sizeof方法
c++中可以使用sizeof()來獲取一個數據類型(包括類和結構體)的數據大小,c++中一個很經典的獲取數組長度的方法就是sizeof(數組)/sizeof(數據)
而java中由於JVM的特性,所有基本數據類型的長度都是確定的,因此所有長度都是確定的,所以Java中沒有sizeof方法,求數組長度只需要使用length屬性即可。

繼承時的重寫和隱藏
繼承時對於Java和c++共同的點就是數據的隱藏,在繼承時,子類和父類的同名數據是分開存放的,子類對象中也可以調用父類的同名數據成員,這是數據的隱藏。但在方法上Java和c++就是不同的機制。c++的函數同樣也是隱藏,也就是子類中可以調用父類的同名方法,但Java就是方法的覆蓋,子類的同名方法會覆蓋父類方法,也就是父類同名方法無法被調用。

虛函數和抽象方法
C++中的有虛函數的概念,用virtual 關鍵字來表示。每個類都會有一個虛函數表,該虛函數表首先會從父類中繼承得到父類的虛函數表, 如果子類中重寫了父類的虛函數(不管重寫後的函數是否爲虛函數),要調用哪個虛函數,是根據當前實際的對象來判斷的(不管指針所屬類型是否爲當前類,有可 能是父類型),指針當前指向的是哪種類型的對象,就調用哪個類型中類定義的虛函數。每個類只有一張虛擬函數表,所有的對象共用這張表。
C++的函數多態就是通過虛函數來實現的。C++中,如果函數不是虛函數,則調用某個函數,是根據當前指針類型來判斷的,並不是根據指針所指向對象的類型。所以虛函數可以實現動態綁定,析構函數一般會是虛函數。
java中沒有虛函數的概念,但是有抽象函數的概念,用abstract關鍵字表示,java中抽象函數必須在抽象類中,而且抽象 函數不能有函數體,抽象類不能被實例化,只能由其子類實現抽象函數,如果某個抽象類的子類仍是抽象類,那麼該子類不需要實現其父類的抽象函數。
這樣來看,Java的抽象函數和c++中的虛函數並不對應,而應該和c++的純虛函數對應,兩者有很多相似之處,而c++中的虛基類,則和java中接口更加相像。

傳參默認參數
我們知道c++是可以允許默認參數的存在,但是Java並不允許。c++中的默認參數使用起來非常方便,但Java也有自己獨特的機制來實現,那就是函數的重載,通過函數的重載實現多種參數情況下的多態,再通過重載的函數之間互相的調用來簡化代碼,實現類似默認參數的功能。

模板類
在代碼翻譯過程中很大的問題就是模板類,Java提供了類似於c++的模板類機制,但是很重要的一點就是Java的泛型問題。Java的泛型是僞泛型,這是因爲Java在編譯期間,所有的泛型信息都會被擦掉,正確理解泛型概念的首要前提是理解類型擦除。Java的泛型基本上都是在編譯器這個層次上實現的,在生成的字節碼中是不包含泛型中的類型信息的,使用泛型的時候加上類型參數,在編譯器編譯的時候會去掉,這個過程成爲類型擦除。

如在代碼中定義List和List等類型,在編譯後都會變成List,JVM看到的只是List,而由泛型附加的類型信息對JVM是看不到的。Java編譯器會在編譯時儘可能的發現可能出錯的地方,但是仍然無法在運行時刻出現的類型轉換異常的情況,類型擦除也是Java的泛型與C++模板機制實現方式之間的重要區別。
而Java本身提供了一個泛型數組arraylist,用這個來操作泛型就會更加方便。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章