C++ 和java的不同點

smilestone322發表於2016-03-18

1)類的靜態成員變數訪問問題

c++ 非靜態的成員函式不能訪問靜態成員,而java可以;
靜態變數和靜態方法既可以在類的例項方法中使用,也可以在類的靜態方法中使用;但是,例項變數和例項方法只能在例項方法中使用,不能在靜態方法中使用;
因為靜態變數和靜態方法不屬於某個特定的物件。

 

#include "stdafx.h"



class A
{
public:
	A(){
		
	}

	static int getCount(){
		return count;
	}

protected:
private:
	static int count;
};

 int A::count=2;

int _tmain(int argc, _TCHAR* argv[])
{
	A aa;

	printf("count=%d\n",A::getCount());

	return 0;
}


 

2)函式的引數傳遞

函式形參和實參 怎麼傳遞?

 

java:
當傳遞基本資料型別引數時,傳遞的實參的值,在這種情況下,形參的改變並不會影響實參的值;

傳遞引用型別的引數時,傳遞的是物件的引用,引用上的傳值在語義上最好描述為傳共享(pass-by-sharing);也就是說,在
方法中引用的物件和傳遞的物件是一樣的。 傳引用,比如String;

void convert(String src,String dest) 

{

         dest="hello";

}

 

在函式內對dest重新賦值,不會改變實參,如果需要改變實參,在傳引用的情況,只有改變物件指向的內容;

 

而對於C++ 可以通過應用,從函式中帶出資訊;

比如:

void convert(const std::string src,std::string &dest)

{

       //

 

}

這樣在函式中改變dest,是可以改變實參的值的;事實上,java中只有值傳遞,沒有引用傳遞,傳遞物件,是物件的拷貝,改變的是物件裡面的內容。所以看起來像C++的引用傳遞。

 

 http://www.codeceo.com/article/top-10-online-compiler.html


3)java中為什麼要把main方法定義為一個static方法?而C++沒有?

  (1)在類中,變數的前面有修飾符static稱為靜態變數(類變數),方法的前面有修飾符static稱為靜態方法(類方法)。靜態方法和靜態變數是屬於某一個類,而不屬於類的物件。
  (2)靜態方法和靜態變數的引用直接通過類名引用。

例如:類Point中有個 static int x;類變數,我們要引用它:Point.x=89;
  (3)在靜態方法中不能呼叫非靜態方法和引用非靜態的成員變數。反之,則可以。

原因:靜態變數和靜態方法在類被載入的時候就分配了記憶體空間,當非靜態的方法呼叫他們的時候,他們已經有了記憶體空間,當然是可以呼叫的咯!
  (4)可以用類的物件去呼叫靜態的方法。   

    我們知道,在C/C++當中,這個main方法並不是屬於某一個類的,它是一個全域性的方法,所以當我們執行的時候,c++編譯器很容易的就能找到這個main方法,然而當我們執行一個java程式的時候,因為java都是以類作為程式的組織單元,當我們要執行的時候,我們並不知道這個main方法會放到哪個類當中,也不知道是否是要產生類的一個物件,為了解決程式的執行問題,我們將這個main方法定義為static,這樣的話,當我們在執行一個java程式碼的時候,我們在命令提示符中寫:java Point(Point為一個類),直譯器就會在Point這個類當中,去呼叫這個靜態的main方法,而不需要產生Point這個類的物件,當我們載入Point這個類的時候,那麼main方法也被載入了,作為我們java程式的一個入口。


4)C++和Java的 非靜態函式可以訪問靜態函式,而反過來 不行 ,在C++中靜態成員函式需要訪問非靜態成員,需要傳遞 this指標;

C++的非靜態函式 可以通過類名和類的物件訪問,通過物件訪問其實就是通過類名訪問;


5) Java類成員的四種訪問許可權

Java中的訪問許可權控制符有四個. 
作用域         當前類          同一package           子孫類                其他package 
public              √                    √                           √                             √ 
protected         √                    √                            √                            × 
friendly            √                    √                            ×                            × 
private             √                     ×                            ×                             × 

沒有時預設為friendly,如建構函式等~這個和C++是不同的,C++預設是私有的,類外無法訪問,而java是friendly,在當前類和同一個包內都可以訪問。


 

Java語言中有4種訪問修飾符:package(預設)、private、public和protected.

1。package是預設的保護模式,又叫做包訪問,沒有任何修飾符時就採用這種保護模式。包訪問允許域和方法被同一個包內任何類的任何方法訪問。(包內訪問)

2。private標識的訪問模式,表示私有的域和方法只能被同一個類中的其他方法訪問,實現了資料隱藏;必要時,可以通過方法訪問私有變數。(類內訪問)

3。public修飾符用於暴露域和方法,以便在類定義的包外部能訪問它們。對包和類中必要的介面元素,也需要使用這個級別;main()方法必須是public的,toString()方法也必須是public的。一般不會用public暴露一個域,除非這個域已經被宣告為final。(跨包訪問)

4。protected修飾符提供一個從包外部訪問包(有限制)的方法。在域和方法前增加protected修飾符不會影響同一個包內其他類和方法對它們的訪問。要從包外部訪問包(其中含有protected成員的類),必須保證被訪問的類是帶有protected成員類的子類。也就是說,希望包中的一個類被包之外的類繼承重用時,就可以使用這個級別。一般應該慎用。(包中類被包外類繼承重用)。


6)java支援C++類似的STL嗎?Java中Vector和ArrayList的區別

      首先看這兩類都實現List介面,而List介面一共有三個實現類,分別是ArrayList、Vector和LinkedList。List用於存放多個元素,能夠維護元素的次序,並且允許元素的重複。3個具體實現類的相關區別如下:

  1. ArrayList是最常用的List實現類,內部是通過陣列實現的,它允許對元素進行快速隨機訪問。陣列的缺點是每個元素之間不能有間隔,當陣列大小不滿足時需要增加儲存能力,就要講已經有陣列的資料複製到新的儲存空間中。當從ArrayList的中間位置插入或者刪除元素時,需要對陣列進行復制、移動、代價比較高。因此,它適合隨機查詢和遍歷,不適合插入和刪除。
  2. Vector與ArrayList一樣,也是通過陣列實現的,不同的是它支援執行緒的同步,即某一時刻只有一個執行緒能夠寫Vector,避免多執行緒同時寫而引起的不一致性,但實現同步需要很高的花費,因此,訪問它比訪問ArrayList慢。
  3. LinkedList是用連結串列結構儲存資料的,很適合資料的動態插入和刪除,隨機訪問和遍歷速度比較慢。另外,他還提供了List介面中沒有定義的方法,專門用於操作表頭和表尾元素,可以當作堆疊、佇列和雙向佇列使用。

     檢視Java原始碼,發現當陣列的大小不夠的時候,需要重新建立陣列,然後將元素拷貝到新的陣列內,ArrayList和Vector的擴充套件陣列的大小不同。



java ArrayList和LinkedList的區別參考如下連結。

http://pengcqu.iteye.com/blog/502676


 7)java和C++ 陣列的區別

JAVA裡陣列的記憶體分配是在堆裡面的,必須用new來分配,而C++裡面是在棧裡面分配的,定義的時候會自動分配

java中的陣列

1、陣列不是集合,它只能儲存同種型別的多個原始型別或者物件的引用。陣列儲存的僅僅是物件的引用,而不是物件本身。陣列宣告的兩種形式:一、int[] arr; 二、int arr[];  推薦使用前者,這是一個int陣列物件,而不是一個int原始型別。

2、陣列本身就是物件,Java中物件是在堆中的,因此陣列無論儲存原始型別還是其他物件型別,陣列物件本身是在堆中的。

4、在陣列宣告中包含陣列長度永遠是不合法的!如:int[5] arr; 。因為,宣告的時候並沒有例項化任何物件,只有在例項化陣列物件時,JVM才分配空間,這時才與長度有關。

5、在陣列構造的時候必須指定長度,因為JVM要知道需要在堆上分配多少空間。例:int[] arr = new int[5];

7、一維陣列的構造。形如:String[] sa = new String[5];  或者分成兩句:String[] sa;  sa = new String[5];

8、原始型別陣列元素的預設值。對於原始型別陣列,在用new構造完成而沒有初始化時,JVM自動對其進行初始化。預設值:byte、short、 int、long--0  float--0.0f double--0.0  boolean--false  char--'"u0000'。(無論該陣列是成員變數還是區域性變數)

10、物件型別的陣列雖然被預設初始化了,但是並沒有呼叫其建構函式。(C++中則會呼叫)也就是說:Car[] myCar = new Car[10];只建立了一個myCar陣列物件!並沒有建立Car物件的任何例項!

11、多維陣列的構造。float[][] ratings = new float[9][]; 第一維的長度必須給出,其餘的可以不寫,因為JVM只需要知道賦給變數ratings的物件的長度。

12、陣列索引的範圍。陣列中各個元素的索引是從0開始的,到length-1。每個陣列物件都有一個length屬性,它儲存了該陣列物件的長度。(注意和String物件的length()方法區分開來)

13、Java有陣列下標檢查,當訪問超出索引範圍時,將產生ArrayIndexOutOfBoundsException執行時異常。注意,這種下標檢查不是在編譯時刻進行的,而是在執行時!也就是說int[] arr = new int[10];  arr[100] = 100; 這麼明顯的錯誤可以通過編譯,但在執行時丟擲!

Java中的陣列中既可以儲存基本的值型別,也可以儲存物件。物件陣列和原始資料型別陣列在使用方法上幾乎是完全一致的,唯一的差別在於物件陣列容納的是引用而原始資料型別陣列容納的是具體的數值。在討論關於陣列的問題時,一定要先確定陣列中儲存的是基本值型別還是物件。特別是在除錯程式時,要注意這方面。



8)

Java中的抽象函式與C++中的虛擬函式 轉自:http://www.cnblogs.com/yhlx/articles/2177756.html

1:java中沒有虛擬函式的概念,但是有抽 象函式的概念,用abstract關鍵字表示,java中抽象函式必須在抽象類中,而且抽象 函式不能有函式體,抽象類不能被例項化,只能由其子類實現抽象函式,如果某個抽象類的子類仍是抽象類,那麼該子類不需要實現其父類的抽象函式。

2:C++中的有虛擬函式的概念,用virtual 關鍵字來表示,每個類都會有一個虛擬函式表,該虛擬函式表首先會從父類中繼承得到父類的虛擬函式表, 如果子類中重寫了父類的虛擬函式(不管重寫後的函式是否為虛擬函式),要呼叫哪個虛擬函式,是根據當前實際的物件來判斷的(不管指標所屬型別是否為當前類,有可 能是父型別),指標當前指向的是哪種型別的物件,就呼叫哪個型別中類定義的虛擬函式。每個類只有一張虛擬函式表,所有的物件共用這張表。

C++的函式多型就是通過虛擬函式來實現的。

3:C++中,如果函式不是虛擬函式,則呼叫某個函式,是根據當前指標型別來判斷的,並不是根據指標所指向物件的型別。

4:Java中,如果函式不是抽象函式,而是一個普通函式,它是預設實現類似C++中虛擬函式功能的,也就是說,呼叫某個函式,是根據當前指標所指向物件的型別來判斷的,而不是根據指標型別判斷。正好與C++中的普通函式相反。即:JAVA裡自動實現了虛擬函式。

C++ Java
虛擬函式 -------- 普通函式
純虛擬函式 -------- 抽象函式
抽象類 -------- 抽象類
虛基類 -------- 介面

純虛擬函式: 主要特徵是不能被用來宣告物件,是抽象類,是用來確保程式結構與應用域的結構據具有直接對映關係的設計工具。帶有純虛擬函式的類稱為抽象類,抽象類能被子類 繼承使用,在子類中必須給出純虛擬函式的實現,如果子類未給出該純虛擬函式的實現,那麼該子類也是抽象類,只有在子類不存在純虛擬函式時,子類才可以用來宣告對 象!抽象類也能用於宣告指標或引用,或用於函式宣告中。具有抽象類特性的類還有建構函式和解構函式,全部是保護的類。如果沒有給出純虛擬函式的實現,則在它 所在的類的建構函式或解構函式中不能直接或間接的呼叫它。純虛擬函式的實現可以在類宣告外進行定義。



5. C++中一般都是把解構函式宣告為虛擬函式。因為虛擬函式可以實現動態繫結,也就是到底呼叫哪個函式是根據指標當前指向哪個物件來確定的,不是根據指標的型別 來確定。如果C++中不把解構函式宣告為虛擬函式,那麼其有個子類,重寫了虛擬函式,那麼當父類指標指向一個子類物件時,當呼叫解構函式時,只呼叫父類的析構 函式,而無法呼叫子類的解構函式,所以一般情況是把解構函式宣告為虛擬函式,實現動態繫結。當然如果一個類不包含虛擬函式,這經常預示不打算將它作為基類使 用。當一個類不打算作為基類時,將解構函式宣告為虛擬通常是個壞主意。
標準 string 型別不包含虛擬函式,如果把String作為基類繼承得到子類會出問題。
總之:多型基類應該宣告虛解構函式。如果一個類有任何虛擬函式,它就應該有一個虛解構函式;如果不是設計用於做基類或不是設計用於多型,這樣的類就不應該宣告虛解構函式。


 9)java 串列埠通訊問題

    java串列埠通有有一個RXTX庫,下載連結如下:

 http://fizzed.com/oss/rxtx-for-java


10)eclipse 使用常見問題

10.1)eclipse 中找不到design介面了

在程式碼中點右鍵,選擇選單Open with,然後點選熟悉的WindowsBuilder Editor



11)C++ lambda 表示式 


程式碼如下:

#include<iostream>
using namespace std;
 
int main()
{
    int a = 1;
    int b = 2;
 
    auto func = [=, &b](int c)->int {return b += a + c;};
    return 0;
}

當我第一次看到這段程式碼時,我直接凌亂了,直接看不懂啊。上面這段程式碼,如果你看懂了,下面的內容就當時複習了;如果看不懂了,就接著和我一起總結吧。

基本語法

簡單來說,Lambda函式也就是一個函式,它的語法定義如下:

複製程式碼程式碼如下:

[capture](parameters) mutable ->return-type{statement}

1.[capture]:捕捉列表。捕捉列表總是出現在Lambda函式的開始處。實際上,[]是Lambda引出符。編譯器根據該引出符判斷接下來的程式碼是否是Lambda函式。捕捉列表能夠捕捉上下文中的變數以供Lambda函式使用;

2.(parameters):引數列表。與普通函式的引數列表一致。如果不需要引數傳遞,則可以連同括號“()”一起省略;

3.mutable:mutable修飾符。預設情況下,Lambda函式總是一個const函式,mutable可以取消其常量性。在使用該修飾符時,引數列表不可省略(即使引數為空);

4.->return-type:返回型別。用追蹤返回型別形式宣告函式的返回型別。我們可以在不需要返回值的時候也可以連同符號”->”一起省略。此外,在返回型別明確的情況下,也可以省略該部分,讓編譯器對返回型別進行推導;

5.{statement}:函式體。內容與普通函式一樣,不過除了可以使用引數之外,還可以使用所有捕獲的變數。

與普通函式最大的區別是,除了可以使用引數以外,Lambda函式還可以通過捕獲列表訪問一些上下文中的資料。具體地,捕捉列表描述了上下文中哪些資料可以被Lambda使用,以及使用方式(以值傳遞的方式或引用傳遞的方式)。語法上,在“[]”包括起來的是捕捉列表,捕捉列表由多個捕捉項組成,並以逗號分隔。捕捉列表有以下幾種形式:

1.[var]表示值傳遞方式捕捉變數var;
2.[=]表示值傳遞方式捕捉所有父作用域的變數(包括this);
3.[&var]表示引用傳遞捕捉變數var;
4.[&]表示引用傳遞方式捕捉所有父作用域的變數(包括this);
5.[this]表示值傳遞方式捕捉當前的this指標。

上面提到了一個父作用域,也就是包含Lambda函式的語句塊,說通俗點就是包含Lambda的“{}”程式碼塊。上面的捕捉列表還可以進行組合,例如:

1.[=,&a,&b]表示以引用傳遞的方式捕捉變數a和b,以值傳遞方式捕捉其它所有變數;
2.[&,a,this]表示以值傳遞的方式捕捉變數a和this,引用傳遞方式捕捉其它所有變數。

不過值得注意的是,捕捉列表不允許變數重複傳遞。下面一些例子就是典型的重複,會導致編譯時期的錯誤。例如:

3.[=,a]這裡已經以值傳遞方式捕捉了所有變數,但是重複捕捉a了,會報錯的;
4.[&,&this]這裡&已經以引用傳遞方式捕捉了所有變數,再捕捉this也是一種重複。


相關文章