您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關C++中如何使用const關鍵字,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
const關鍵字
常類型是指使用類型修飾符const說明的類型,常類型的變量或對象的值是不能被更新的。不管出現在任何上下文都是為這個目的而服務的。
const使用方法
定義const對象
const修飾符可以把對象轉變成常數對象,意思就是說利用const進行修飾的變量的值在程序的任意位置將不能再被修改,就如同常數一樣使用!任何修改該變量的嘗試都會導致編譯錯誤:
注意:因為常量在定以后就不能被修改,所以定義時必須初始化:
對于類中的const成員變量必須通過初始化列表進行初始化,如下所示:
const對象默認為文件的局部變量
在全局作用域里定義非const變量時,它在整個程序中都可以訪問,我們可以把一個非const變量定義在一個文件中,假設已經做了合適的聲明,就可以在另外的文件中使用這個變量:
與其他變量不同,除非特別說明,在全局作用域聲明的const變量是定義該對象的文件的局部變量。此變量只存在于那個文件中,不能被其他文件訪問。通過指定const變量為extern,就可以在整個程序中訪問const對象。
注意:非const變量默認為extern。要使const變量能夠在其他文件中訪問,必須在文件中顯式地指定它為extern。
const 引用
const引用是指向const對象的引用:
可以讀取但不能修改refVal,因此,任何對refVal的賦值都是不合法的。這個限制有其意義:不能直接對ival賦值,因此不能通過使用refVal來修改ival。同理,用ival初始化ref2也是不合法的:ref2是普通的非const引用,因此可以用來修改ref2指向的對象的值。通過ref2對ival賦值會導致修改const對象的值,為防止這樣的修改,需要規定將普通的引用綁定到const對象是不合法的。 const 引用可以初始化為不同類型的對象或者初始化為右值。如字面值常量:
同樣的初始化對于非const引用卻是不合法的,而且會導致編譯時錯誤。其原因非常微妙,值得解釋一下。觀察將引用綁定到不同的類型時所發生的事情,最容易理解上述行為。對于下一段代碼:
編譯器會將這些代碼轉換為一下形式:
我們發現編譯器會創建一個int型的暫時變量存儲dval,然后將ri綁定到temp上。
注意:引用在內部存放的是一個對象的地址,它是該對象的別名。對于不可尋址的值,如文字常量,以及不同類型的對象,編譯器為了實現引用,必須生成一個臨時對象,引用實際上指向該對象,但用戶不能訪問它。
如果ri不是const,那么可以給ri賦一新值。這樣做不會修改dval的,而是修改了temp。期望對ri賦值會修改dval的程序員會發現dval沒有被修改。僅允許const引用綁定到需要臨時使用的值完全避免了這個問題,直接告訴程序員不能修改,因為const引用是只讀的哈~(其實就是避免程序員心理預期產生反差。。。)
注意:非const引用只能綁定到與該引用相同類型的對象。 const引用則可以綁定到不同但相關的類型的對象或綁定到右值。
const對象的動態數組
如果我們在自由存儲區中創建的數組存儲了內置類型的const對象,則必須為這個數組提供初始化: 因為數組元素都是const對象,無法賦值。實現這個要求的唯一方法是對數組做值初始化。
C++允許定義類類型的const數組,但該類類型必須提供默認構造函數:
這里便會調用string類的默認構造函數初始化數組元素。
指針和const限定符的關系(重點!!!!!!!非常容易搞混)
const限定符和指針結合起來常見的情況有以下幾種。
指向常量的指針(指向const對象的指針)
C++為了保證不允許使用指針改變所指的const值這個特性,強制要求這個指針也必須具備const特性:
這里cptr是一個指向double類型const對象的指針,const先頂了cptr指向的對象的類型,而并非cptr本身,所以cptr本身并不是const。所以定義的時候并不需要對它進行初始,如果需要的話,允許給cptr重新賦值,讓其指向另一個const對象。但不能通過cptr修改其所指對象的值。
而我們將一個const對象的地址賦給一個普通的非const指針也會導致編譯錯誤。
不能使用void*指針保存const對象的地址,必須使用const void*類型的指針保存const對象的地址。
下面令人頭暈的一個問題來了----à 允許把非const對象的地址賦給指向const對象的指針,例如:
但是我們不能通過cptr指針來修改dval的值!!!即使它指向的是非const對象。
然后,我們一定要知道,不能使用指向const對象的指針修改基礎對象,然而如果該指針指向了非const對象,可用其他方式修改其所指的對象,所以事實上,可以修改const指針所指向的值的,但是不能通過const對象指針來進行而已!如下所示:
通過以上,我們知道指向const對象的指針 確切的講: 自以為指向const的指針!
常指針(const指針)
C++中還提供了const指針——本身的值不能被修改。
我們可以從右往左把上述定義語句讀作"指向int型對象的const指針"。與其他const量一樣,const指針的值不能被修改,這意味著不能使curErr指向其他對象。Const指針也必須在定義的時候初始化。
指針本身是const的試試并沒有說明是否能用改真真修改其所指向的對象的值。指針對象的值能否修改完全取決于該對象的類型。
指向常量的常指針(指向const對象的const指針)
如下可以這樣定義:
這樣pi_ptr首先是一個const指針,然后其指向一個const對象~~~
函數和const限定符的關系(另一難點!!!理解)
類中的const成員函數(常量成員函數)
在一個類中,任何不會修改數據成員的函數都應該聲明為const類型。如果在編寫const成員函數時,不慎修改了數據成員,或者調用了其它非const成員函數,編譯器將指出錯誤,這無疑會提高程序的健壯性。使用const關鍵字進行說明的成員函數,稱為常成員函數。只有常成員函數才有資格操作常量或常對象,沒有使用const關鍵字說明的成員函數不能用來操作常對象。常成員函數說明格式如下:
<類型說明符> <函數名> (<參數表>) const;
其中,const是加在函數說明后面的類型修飾符,它是函數類型的一個組成部分,因此,在函數實現部分也要帶const關鍵字。下面舉一例子說明常成員函數的特征。
函數重載
既然const是定義為const函數的組成部分,那么就可以通過添加const實現函數重載咯。
其中print成員函數就實現了兩個版本~~~ 重載哦,輸出結果為 5,52。 const對象默認調用const成員函數。
const 修飾函數返回值
const修飾函數返回值其實用的并不是很多,它的含義和const修飾普通變量以及指針的含義基本相同。如下所示:
一般情況下,函數的返回值為某個對象時,如果將其聲明為const時,多用于操作符的重載。通常,不建議用const修飾函數的返回值類型為某個對象或對某個對象引用的情況。原因如下:如果返回值為某個對象為const(const A test = A 實例)或某個對象的引用為const(const A& test = A實例) ,則返回值具有const屬性,則返回實例只能訪問類A中的公有(保護)數據成員和const成員函數,并且不允許對其進行賦值操作,這在一般情況下很少用到。
const修飾函數參數
傳遞過來的參數在函數內不可以改變(無意義,因為Var本身就是形參)
參數指針所指內容為常量不可變
參數指針本身為常量不可變(也無意義,因為char* Var也是形參)
參數為引用,為了增加效率同時防止修改。修飾引用參數時:
這樣的一個const引用傳遞和最普通的函數按值傳遞的效果是一模一樣的,他禁止對引用的對象的一切修改,唯一不同的是按值傳遞會先建立一個類對象的副本, 然后傳遞過去,而它直接傳遞地址,所以這種傳遞比按值傳遞更有效.另外只有引用的const傳遞可以傳遞一個臨時對象,因為臨時對象都是const屬性, 且是不可見的,他短時間存在一個局部域中,所以不能使用指針,只有引用的const傳遞能夠捕捉到這個家伙.
const限定符和static的區別
const定義的常量在超出其作用域之后其空間會被釋放,而static定義的靜態常量在函數執行后不會釋放其存儲空間。static表示的是靜態的。類的靜態成員函數、靜態成員變量是和類相關的,而不是和類的具體對象相關的。即使沒有具體對象,也能調用類的靜態成員函數和成員變量。一般類的靜態函數幾乎就是一個全局函數,只不過它的作用域限于包含它的文件中。在C++中,static靜態成員變量不能在類的內部初始化。在類的內部只是聲明,定義必須在類定義體的外部,通常在類的實現文件中初始化,如:double Account::Rate=2.25; static關鍵字只能用于類定義體內部的聲明中,定義時不能標示為static在C++中,const成員變量也不能在類定義處初始化,只能通過構造函數初始化列表進行,并且必須有構造函數。const數據成員,只在某個對象生存期內是常量,而對于整個類而言卻是可變的。因為類可以創建多個對象,不同的對象其const數據成員的值可以不同。所以不能在類的聲明中初始化const數據成員,因為類的對象沒被創建時,編譯器不知道const數據成員的值是什么。
const數據成員的初始化只能在類的構造函數的初始化列表中進行。要想建立在整個類中都恒定的常量,應該用類中的枚舉常量來實現,或者static const。
const成員函數主要目的是防止成員函數修改對象的內容。即const成員函數不能修改成員變量的值,但可以訪問成員變量。當方法成員函數時,該函數只能是const成員函數。
static成員函數主要目的是作為類作用域的全局函數。不能訪問類的非靜態數據成員。類的靜態成員函數沒有this指針,這導致:
1、不能直接存取類的非靜態成員變量,調用非靜態成員函數
2、不能被聲明為virtual
其中關于static、const、static cosnt、const static成員的初始化問題:
類里的const成員初始化在一個類里建立一個const時,不能給他初值
類里的const成員初始化
類中的static變量是屬于類的,不屬于某個對象,它在整個程序的運行過程中只有一個副本,因此不能在定義對象時 對變量進行初始化,就是不能用構造函數進行初始化,其正確的初始化方法是:
數據類型 類名::靜態數據成員名=值
類里的static cosnt 和 const static成員初始化(這兩種寫法是一致的!!)
最后通過一個完整的例子展示以上結果:
const 的難點
如果函數需要傳入一個指針,面試官可能會問是否需要為該指針加上const,把const加在指針不同的位置有什么區別;如果寫的函數需要傳入的參數是一個復雜類型的實例,面試官可能會問傳入值參數或者引用參數有什么區別,什么時候需要為傳入的引用參數加上const。 const是用來聲明一個常量的,當你不想讓一個值被改變時就用const,const int max和int const max 是沒有區別的,都可以。不涉及到指針const很好理解。一旦涉及到指針,則比較容易出問題。
如果const位于星號的左側,則const就是用來修飾指針所指向的變量,即指針指向的對象為常量;如果const位于星號的右側,const就是修飾指針本身,即指針本身是常量。
因此,[1]和[2]的情況相同,都是指針所指向的內容為常量(const放在變量聲明符的位置無關),這種情況下不允許對內容進行更改操作,如不能*a = 3 ;[3]為指針本身是常量,而指針所指向的內容不是常量,這種情況下不能對指針本身進行更改操作,如a++是錯誤的;[4]為指針本身和指向的內容均為常量。
如果理解了上面的所有信息,我相信應該問題不大。僅供參考~~~ 希望大家熱烈討論哈。 好了,先寫到這里,在以后需要補充我再加東西吧。。。敲得手疼~~~ ~!!!
下面是其他網友的補充
在類中,如果你不希望某些數據被修改,可以使用const關鍵字加以限定。const 可以用來修飾成員變量、成員函數以及對象。
一、const 成員變量
const 成員變量的用法和普通 const 變量的用法相似,只需要在聲明時加上 const 關鍵字。初始化 const 成員變量只有一種方法,就是通過參數初始化表
二、const 成員函數
const 成員函數可以使用類中的所有成員變量,但是不能修改成員變量,這種措施主要還是為了保護數據而設置的。const 成員函數也稱為常成員函數。
常成員函數需要在聲明和定義的時候在函數頭部的結尾都加上 const 關鍵字,如:
class Student{public: Student(char *name, int age, float score); void show(); //聲明常成員函數 char *getname() const; int getage() const; float getscore() const;private: char *m_name; int m_age; float m_score;};Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){ }void Student::show(){ cout<<m_name<<"的年齡是"<<m_age<<",成績是"<<m_score<<endl;}//定義常成員函數char * Student::getname() const{ return m_name;}int Student::getage() const{ return m_age;}float Student::getscore() const{ return m_score;}
三.const對象
一旦將對象定義為const 對象之后,不管是哪種形式,則該對象就只能訪問被 const 修飾的成員了(包括 const 成員變量和 const 成員函數),因為非 const 成員可能會修改對象的數據(編譯器也會這樣假設),C++禁止這樣做。
例:
#include <iostream>using namespace std;class Student{public: Student(char *name, int age, float score);public: void show(); char *getname() const; int getage() const; float getscore() const;private: char *m_name; int m_age; float m_score;};Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){ }void Student::show(){ cout<<m_name<<"的年齡是"<<m_age<<",成績是"<<m_score<<endl;}char * Student::getname() const{ return m_name;}int Student::getage() const{ return m_age;}float Student::getscore() const{ return m_score;}int main(){ const Student stu("小明", 15, 90.6); //stu.show(); //error cout<<stu.getname()<<"的年齡是"<<stu.getage()<<",成績是"<<stu.getscore()<<endl; const Student *pstu = new Student("李磊", 16, 80.5); //pstu -> show(); //error cout<<pstu->getname()<<"的年齡是"<<pstu->getage()<<",成績是"<<pstu->getscore()<<endl; return 0;}
以上就是C++中如何使用const關鍵字,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。