Java中final與C++中const的關系


Java中的final有三種主要用法:

(1)修飾變量:

final變量是不可改變的,但它的值可以在運行時刻初始化,也可以在編譯時刻初始化,甚至可以放在構造函數中初始化,而不必在聲明的時候初始化,所以下面的語句均合法:

final int i = 1; // 編譯時刻 final int i2 = (int)(Math.Random() * 10); //運行時刻 final int i3; //構造函數里再初始化

final經常和static一起用,這種用法類似C++的常量,在Java中很常見,比如 static final i = 10; 但這里同樣也是允許運行時刻初始化的。

(2)修飾類對象:

而如果修飾類對象,並不表示這個對象不可更改,而是表示這個這個變量不可再賦成其它對象,這就比較象 C++的 Class const * p了(這樣表明這個指向該Class的指針p不能再指向其他對象,指針常量,但是該對象中的值是可以修改的(const Class *p 是常量指針,任何成員變量都不能修改))

final Value v = new Value(); v = new Value(); //不允許! v.some_method(); //允許

(3)修飾方法:

fina修飾的方法是不能被重載的,類似於類中的private方法,所以private方法默認是final的

大致說就是變量不可修改(基本數據類型值不能修改,類類型引用不能修改),方法不可重載,類不可繼承,



C++中的const修飾符有大致四種用法

(1)const修飾變量


普通變量(不是指針變量)以下兩種定義形式在本質上是一樣的。它的含義是:const修飾的類型為TYPE的變量value是不可變的。

TYPE const ValueName = value;
const TYPE ValueName = value;

① const修飾成員變量
const修飾類的成員函數,表示成員常量,不能被修改,同時它只能在初始化列表中賦值。
class A
{

const int nValue; //成員常量不能被修改

A(int x): nValue(x) { } ; //只能在初始化列表中賦值
}


②const修飾成員函數
const修飾類的成員函數,則該成員函數不能修改對象的成員變量,不能調用類中任何非const成員函數。一般寫在函數的最后來修飾。

class A { void function()const; //常成員函數, 它不改變對象的成員變量.  //也不能調用類中任何非const成員函數。 } 

對於const類對象/指針/引用,只能調用類的const成員函數,因此,const修飾成員函數的最重要作用就是限制對於const對象的使用。

a. const成員函數不被允許修改它所在對象的任何一個數據成員。

b. const成員函數能夠訪問對象的const成員,而其他成員函數不可以。


③const修飾類對象/對象指針/對象引用

const Class A const Class *p const Class& ref

· const修飾類對象表示該對象為常量對象,其中的任何成員都不能被修改(這跟Java有很大的區別)。對於對象指針和對象引用也是一樣。

· const修飾的對象,該對象的任何非const成員函數都不能被調用,因為任何非const成員函數會有修改成員變量的企圖。
例如:

class AAA { void func1(); void func2() const; } const AAA aObj; aObj.func1(); //錯誤 aObj.func2(); //正確  const AAA* aObj = new AAA(); aObj-> func1(); //錯誤 aObj-> func2(); //正確 

但是指針常量Class const *p 指的是p的引用不能更改。

這個要注意

(2)將const改為外部連接

作用於擴大至全局,編譯時會分配內存,並且可以不進行初始化,僅僅作為聲明,編譯器認為在程序其他地方進行了定義.

extend const int ValueName = value;


(3)修飾方法:method

修飾方法時,final和C++的const就差別太大了,final表示一個Java函數不可更改,也就是不能被重載了,而不是修飾返回值的,所以private方法自動就是final的了(它們不會被重載)。

帶來的一個附帶的好處就是,final方法可以被編譯器優化,比如內聯什么的,也就是說final的方法可能效率會高一些(僅僅是可能,具體取決於編譯器)。


①const修飾函數參數

a.傳遞過來的參數在函數內不可以改變(無意義,因為Var本身就是形參)

void function(const int Var);

b.參數指針所指內容為常量不可變

void function(const char* Var);

c.參數指針本身為常量不可變(也無意義,因為char* Var也是形參)

void function(char* const Var);

d.參數為引用,為了增加效率同時防止修改。修飾引用參數時:

void function(const Class& Var); //引用參數在函數內不可以改變

void function(const TYPE& Var); //引用參數在函數內為常量不可變

這樣的一個const引用傳遞和最普通的函數按值傳遞的效果是一模一樣的,他禁止對引用的對象的一切修改,唯一不同的是按值傳遞會先建立一個類對象的副本, 然后傳遞過去,而它直接傳遞地址,所以這種傳遞比按值傳遞更有效.另外只有引用的const傳遞可以傳遞一個臨時對象,因為臨時對象都是const屬性, 且是不可見的,他短時間存在一個局部域中,所以不能使用指針,只有引用的const傳遞能夠捕捉到這個家伙.


②const 修飾函數返回值
const修飾函數返回值其實用的並不是很多,它的含義和const修飾普通變量以及指針的含義基本相同。
a.const int fun1() //這個其實無意義,因為參數返回本身就是賦值。
b. const int * fun2() //調用時 const int *pValue = fun2();
//我們可以把fun2()看作成一個變量,即指針內容不可變。
* const fun3() //調用時 int * const pValue = fun2();
//我們可以把fun2()看作成一個變量,即指針本身不可變。

一般情況下,函數的返回值為某個對象時,如果將其聲明為const時,多用於操作符的重載。通常,不建議用const修飾函數的返回值類型為某個對象或對某個對象引用的情況。原因如下:如果返回值為某個對象為const(const A test = A 實例)或某個對象的引用為const(const A& test = A實例) ,則返回值具有const屬性,則返回實例只能訪問類A中的公有(保護)數據成員和const成員函數,並且不允許對其進行賦值操作,這在一般情況下很少用到。

 

(轉載自:https://www.zhihu.com/question/35593391/answer/63576986)

 

一、static
1.static修飾變量
C的局部變量,全局變量(即外部變量)和靜態變量
局部變量:在函數內定義的變量,采用動態存儲方式。
全局變量:在函數外定義的變量,采用靜態存儲方式。
extern: 外部變量的作用域從定義點到文件結束。如果在定義點之前的函數(或其他源文件的函數)想引用該外部變量,則應該在應用之前用關鍵字extern對該變量作‘外部變量聲明’。表示該變量是一個已經定義了的外部變量,就可以合法的調用該外部變量。
靜態變量:靜態變量的初值只在編譯時賦予,且只初始化一次。生存期為整個源程序,作用域為本源文件或函數。采用靜態存儲方式。
靜態全局變量:作用域為本源文件,生命周期是程序生命期。
靜態全局變量的作用:1.不必擔心與其他源文件使用相同變量名 2.不會被其他源文件修改  3.只能在本文件使用
靜態局部變量:作用域為函數,生命周期是程序生命期。
注:使用了大量全局變量的程序維護起來很麻煩,尤其是有許多函數都各自訪問一個全局變量的程序。所以引入了靜態局部變量,但用全局變量也無妨。

JAVA的局部變量,全局變量和成員變量

全局變量:JAVA中不存在全局變量這個概念
局部變量:定義在方法中,需要自己初始化,不可以被訪問控制符及static修飾,可定義成final型
成員變量:定義在類中,JAVA可幫你初始化,可以被訪問控制符(public)及static修飾,可定義成final型
成員變量有兩種:實例變量,類變量(靜態變量)
實例變量(對象變量):沒有static修飾
類變量(靜態變量):由static修飾,被類的實例公用
2.static修飾函數

C的靜態函數

靜態函數:用static修飾的函數,只在本源文件可見
優點:1.不會被其他源文件所用  2.其他文件中可以起相同的函數名字

JAVA的成員方法

成員方法:包括靜態方法,實例方法
類方法(靜態方法):被一個類的所有實例公用
實例方法(對象方法):屬於某個對象

注:1.static方法內部不能引用非static變量。
2.static方法不能被子類重寫為非static方法。
3.父類的非static方法不能被子類重寫為static方法。
4.static代碼塊可以用static {}來完成,在類被第一次裝載時執行初始化,先於靜態方法和其他方法的執行。

3.static修飾內部類


沒有外部類對象時,也能夠訪問靜態內部類。

靜態內部類僅能訪問外部類的靜態成員和方法。


4.static修飾代碼塊


靜態代碼塊與非靜態代碼塊的不同:靜態代碼塊只在第一次new的時候執行,而非靜態代碼塊每一次new都要執行。

JVM加載類的時候執行順序:靜態代碼塊---非靜態代碼塊---主方法


static的含義:1.靜態存儲方式  2.作用域僅限於本文件 3.不需要實例化就可以使用


二、final


1.final修飾變量

final成員變量表示常量,只能被賦值一次,賦值后值不再改變。final經常和static一起使用表示常量(即static final,不用實例化)。

2.final修飾方法

final方法表示不能被子類重寫,但可以被繼承,如果認為一個方法的功能足夠完善,子類不需要改變的話,就聲明為final。final方法比非final方法要快,因為在編譯的時候已經靜態綁定了,不需要在運行時再動態綁定。

重寫(覆蓋):在子類中定義某方法與其父類有相同的名稱,返回類型和參數(有繼承關系)

重載:JAVA中一個類可以有多個同名方法,參數類型或個數等可以不同。(沒有繼承關系)

3.final修飾類

final類功能通常是完整的,它們不能被繼承,沒有子類,Java中有許多類是final的,譬如String, Interger以及其他包裝類。


三、const
const是java中的預留關鍵字(java中預留關鍵字還有goto),現在沒有作為關鍵字,以后的版本中可能擴展用,但現在常用於C,C++中。C中的const類似於final。

(轉載自:https://blog.csdn.net/cwdysg/article/details/60953621)

在C/C++中:

const與指針的幾種結合方式

1.const int *ptr;

2.int const *ptr;

3.int *const ptr;

4.const int *const ptr;

5.int const *const ptr;

其中,1,2兩種聲明表示ptr指向的對象(*ptr表示數據)是只讀的,但是ptr本身是可以改變的(即可以指向其他內容);

           3聲明表示ptr(表示地址)本身是只讀的(即不能改變其值,也就是不能改變其指向);

           4,5兩種聲明表示ptr(表示地址)本身和ptr所指向的對象(*ptr表示數據)都是只讀的。

說明:從指針的角度理解,指針具有右結合性,可以根據指針標識符*來進行判斷結合方式,如果const在*右邊,則表示與*號右邊的部分結合,如果const在*號左邊,則表示與*號及其右邊的整體結合。

(轉載自:https://blog.csdn.net/kkguokai/article/details/9566477 )


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM