在java中,類實(shí)例聲明和構(gòu)造是分開。"T a;"是聲明,而"a=new T();"才是構(gòu)造。引用聲明和C++相同。
但是Java的機(jī)制與C++不同,Java中的引用也叫句柄,或者說句柄才是其真實(shí)名稱。類聲明的都是一個句柄,調(diào)用構(gòu)造函數(shù)才會使得句柄指向類實(shí)例。因此Java中沒有類似于C++中的復(fù)制函數(shù),因為Java的復(fù)制都是直接復(fù)制句柄內(nèi)容。例如"T b=a;"只不過是將a的句柄復(fù)制(賦值)給了b,從而b也指向a指向的類實(shí)例。可以看出Java與C++在此處的不同,Java依然只有一個實(shí)例,而C++則存在了兩個實(shí)例。
所以在函數(shù)中,Java的形參都是入?yún)⒌木浔鷱?fù)制,并且是淺復(fù)制(只復(fù)制該句柄,而不復(fù)制句柄指向的下一層句柄)。因此在函數(shù)中,直接修改形參是不能改變?nèi)雲(yún)⒌摹5侨绻薷男螀⒅赶虻膶ο蟮南乱粚泳浔鷦t會修改入?yún)ⅰR虼嗽贘ava中不存在像C/C++中一樣的Swap函數(shù)。函數(shù)的返回值,也是句柄復(fù)制。如果在函數(shù)中構(gòu)造一個局部變量類實(shí)例,那么是可以返回到外部的,當(dāng)然那個局部變量的句柄是不存在了。Java中要復(fù)制對象,需要重載clone函數(shù),并且要分清是淺復(fù)制還是深復(fù)制(完全構(gòu)造一個新對象,兩者的內(nèi)部數(shù)據(jù)和實(shí)例不相同)。
c++中一個引用指向的地址不會改變,改變的是指向地址的內(nèi)容,然而java中引用指向的地址在變!!如果非要對比著看,那么Java中的“引用”倒是和C/C++的指針更像一些,和C++的“引用”很不一樣。java去除指針概念,就用引用羅... 你看 java: A a = new A(1); A b = new A(2); b = a; 沒有問題,a 和 b引用同一個對象A(2),原來的A(1)成為沒有被引用的對象。 垃圾回收機(jī)制會在之后的某個時刻把A(1)干掉。 而C++則不然。C++的引用就語義上說是“別名”【本質(zhì)是個const指針,又叫指針常量】,而并不是指針的另一種用法: A a = A(1); A b = A(2); A& c = b; //c 是 b的別名 c = a; //并不是 c 引用 a,而是拷貝操作 c.Operator= ( a ) 就語言機(jī)制來說,java的引用是用來管理和命名對象; 而,C++的引用機(jī)制是很純粹的,就是別名而已。 每種語言的特性都是整體的有機(jī)部分。 我們知道, java的引用機(jī)制是一個很復(fù)雜的機(jī)制。他必須區(qū)分“基本對象”和“復(fù)合對象”,你可以想象一下,如果其中沒有基本對象,那么我們?nèi)绾瓮瓿蓪ο蟮膹?fù)制? 唯一的解決方案是提供兩個等于號,或者一律用構(gòu)造函數(shù).... 但是綜合來看,他和垃圾回收形成了相當(dāng)完美的組合方案。而C++ 的引用機(jī)制為運(yùn)算符重載提供了大幅度的支持。C++ 的引用是用類“模擬”基本對象的根本要求。 如果C++使用java那種引用,那么原本漂亮的 operator[]、 PRoxy class 等就很難實(shí)現(xiàn)了。 更進(jìn)一步, C++ 的運(yùn)算符重載對 C++ 的模版機(jī)制提供了強(qiáng)力的支持在c++中,引用只是對于一個變量起的別名,一旦定義就無法修改,即無法再指向其他變量,如程序中,對于a的引用的任何操作都等同于對于a的操作。 java定義的引用并不是這樣。在java中,引用相當(dāng)與指針,它與c中的指針主要有兩個區(qū)別:一是引用不能進(jìn)行地址操作,如數(shù)組的加一 操作,相當(dāng)于引用只是只是指向數(shù)據(jù)的一個副本,而不是數(shù)據(jù)本身,這樣就避免了由于對于地址的誤操作而改變其他變量的值,甚至危害到系統(tǒng)的安全。二是 java中的引用只能指向?qū)ο?/strong>,他的引用是在實(shí)例化對象時系統(tǒng)直接生成的,因此對于普通數(shù)據(jù)類型是不能進(jìn)行引用定義的,如果要對普通數(shù)據(jù)類型進(jìn)行函數(shù)調(diào)用 時的地址傳遞(即java中的引用傳遞),必須把數(shù)據(jù)封裝到類中。java的這種特性使得在java的函數(shù)或類的參數(shù)傳遞時可以實(shí)現(xiàn)與c中指針相同的功能。
具體應(yīng)用
指針和引用在C++中很常用,但是對于它們之間的區(qū)別很多初學(xué)者都不是太熟悉,下面來談?wù)勊麄?者之間的區(qū)別和用法。
1.指針和引用的定義和性質(zhì)區(qū)別:
(1)指針:指針是一個變量,只不過這個變量存儲的是一個地址,指向內(nèi)存的一個存儲單元;而引用跟原來的變量實(shí)質(zhì)上是同一個東西,只不過是原變量的一個別名而已。如:
int a=1;int *p=&a;
int a=1;int &b=a;
上面定義了一個整形變量和一個指針變量p,該指針變量指向a的存儲單元,即p的值是a存儲單元的地址。
而下面2句定義了一個整形變量a和這個整形a的引用b,事實(shí)上a和b是同一個東西,在內(nèi)存占有同一個存儲單元。
(2)可以有const指針,但是沒有const引用;
(3)指針可以有多級,但是引用只能是一級(int **p;合法 而 int &&a是不合法的)
(4)指針的值可以為空,但是引用的值不能為NULL,并且引用在定義的時候必須初始化;
(5)指針的值在初始化后可以改變,即指向其它的存儲單元,而引用在進(jìn)行初始化后就不會再改變了。
(6)"sizeof引用"得到的是所指向的變量(對象)的大小,而"sizeof指針"得到的是指針本身的大小;
(7)指針和引用的自增(++)運(yùn)算意義不一樣;
我選擇寫 C++ 中的引用是因為我感覺大多數(shù)人誤解了引用。而我之所以有這個感受是因為我主持過很多 C++ 的面試,并且我很少從面試者中得到關(guān)于 C++ 引用的正確答案。
那么 c++ 中引用到底意味這什么呢?通常一個引用讓人想到是一個引用的變量的別名,而我討厭將 c++ 中引用定義為變量的別名。這篇文章中,我將盡量解釋清楚, c++ 中根本就沒有什么叫做別名的東東。
背景
在 c/c++ 中,訪問一個變量只能通過兩種方式被訪問,傳遞,或者查詢。這兩種方式是:
1. 通過值 訪問 / 傳遞變量
2. 通過地址 訪問 / 傳遞變量 – 這種方法就是指針
除此之外沒有第三種訪問和傳遞變量值的方法。引用變量也就是個指針變量,它也擁有內(nèi)存空間。最關(guān)鍵的是引用是一種會被編譯器自動解引用的指針。很難相信么?讓我們來看看吧。。。
引用其實(shí)就是 c++ 中的指針常量。表達(dá)式 int &i = j; 將會被編譯器轉(zhuǎn)化成 int *const i = &j; 而引用之所以要初始化是因為 const 類型變量必須初始化,這個指針也必須有所指。下面我們再次聚焦到上面這段代碼,并使用編譯器的那套語法將引用替換掉。
新聞熱點(diǎn)
疑難解答
圖片精選