詳解C/C++中const限定符總結(jié)
const限定符
const是一種限定符,被const所限定的變量其值不可以被改變。
const的初始化
由于const一旦創(chuàng)建其值就不能夠被改變,所以我們必須對(duì)其進(jìn)行初始化
const int a;//錯(cuò)誤,const變量必須進(jìn)行初始化! const int b=10;//正確,編譯時(shí)初始化 const int c=get_size();//正確,運(yùn)行時(shí)初始化
相同類型的變量相互初始化時(shí),不論變量是否被const限定我們都可以進(jìn)行隨意的相互拷貝。因?yàn)樵诳截愡^程中我們只會(huì)用到等式右邊變量的右值屬性,無須在意其是否可以改變。
int m = 5; const int n = m; int j = n;
const與指針
頂層const與底層const
對(duì)于指針來說,由于其指向另一片內(nèi)存的特點(diǎn),有三種不同的const情況,即:
- 指向常量的指針(const int *)
- 常量指針(int * const)
- 指向常量的常量指針(const int *const)
我們一般稱符合第一種情況的為具有底層const屬性。
符合第二種情況的為具有頂層const屬性。
第三種情況兼而有之。
關(guān)于帶有const的指針的相互賦值(或者初始化)問題
- 頂層const并不會(huì)影響變量間的相互拷貝(原因是頂層const只保證自身的值不會(huì)改變,const沒有改變自身的變量類型,在拷貝時(shí)只是使用該類型的右值)。
- 如果等號(hào)右邊是底層const,那么等號(hào)左邊必須保證為相同的底層const(或者等號(hào)右邊的類型可以轉(zhuǎn)換成等號(hào)左邊的類型),否者表達(dá)式無法通過編譯。
關(guān)于底層與頂層const的一些想法
const的底層與頂層屬性似乎只在指針上存在。但是c++primer中有這樣的代碼和注釋:
const int ci=1,&cr=ci; auto b=ci;//b是一個(gè)整數(shù)(ci的頂層const特性被忽略掉了) auto c=cr;//c是一個(gè)整數(shù)(cr是ci的別名,ci本身是一個(gè)頂層const)
這段代碼是為了說明auto說明符一般會(huì)忽略掉頂層const的特性,在注釋中明確寫著 ci本身是一個(gè)頂層const 。
這也與我的看法一致,底層與頂層const實(shí)際上并不是指針?biāo)赜械?,只要是不能改變?duì)象自身的對(duì)象都具有頂層const,而不能改變自己所指向的對(duì)象的對(duì)象都具有底層const。
從這個(gè)角度看,引用實(shí)際上自帶頂層const。
底層const的隱式轉(zhuǎn)換
上面提到,只有在等號(hào)右邊和等號(hào)左邊的類型具有相同的底層const屬性,才可以進(jìn)行賦值或者初始化。
然而有些時(shí)候等號(hào)右邊可能并不具有和等號(hào)左邊一致的底層const卻依然可以成立,這是因?yàn)榈忍?hào)右邊的類型發(fā)生了隱式轉(zhuǎn)換從而具有了和等號(hào)左邊類型相同底層const屬性。
例如:
int i=5; int *p=&i; const int *cp=p//int*隱式轉(zhuǎn)換稱為了const int*
為什么int 轉(zhuǎn)換成const int 被設(shè)定為合法的呢,因?yàn)樵趯nt 轉(zhuǎn)換為const int 的過程中用戶的權(quán)限變小了,在這一轉(zhuǎn)換過程中并不會(huì)使程序變得不可靠。
由此我們可以得知非底層const的指針是可以通過隱式轉(zhuǎn)換轉(zhuǎn)變成底層const的。
const與引用
可以把引用綁定在const的變量上,稱為const的引用,對(duì)常量的引用。
與普通的引用不同的是,對(duì)常量的引用不能被用作修改它所綁定的對(duì)象
const int ci=5; const int &r=ci; r=6//錯(cuò)誤不可以通過常引用來修改值 int &r2=ci//錯(cuò)誤,試圖讓一個(gè)非常量引用指向一個(gè)常量對(duì)象。
const引用的初始化
我們知道對(duì)于引用來說初始化時(shí)一定要用一個(gè)對(duì)象初始化,且該對(duì)象的類型需要與之匹配。
但是const的引用是個(gè)例外,在初始化常量引用時(shí)允許用任意表達(dá)式作為初始值,只要該表達(dá)式的結(jié)果能轉(zhuǎn)換成引用的類型即可,甚至允許為一個(gè)常量引用綁定非常量的對(duì)象、字面值或者是表達(dá)式。
int i=42; const int &r1=i;//允許將const int&綁定到一個(gè)普通int對(duì)象上 const int &r2=3.14;//正確:r2是一個(gè)常量引用 const int &r3=r1*2;//正確:r3是一個(gè)常量引用 int &r4 =r1*2;//錯(cuò)誤,非常量引用不能用表達(dá)式初始化
C++primer中給出了可以這么做的原因:
要想理解這種例外情況的原因,最簡(jiǎn)單的方法是弄清楚當(dāng)一個(gè)常量引用被綁定到另外一種類型上都時(shí)到底發(fā)生了什么:
double dval=3.14; const int &ri=dval;
此處ri引用了一個(gè)int型的數(shù)。對(duì)ri的操作應(yīng)該是整數(shù)運(yùn)算,但dval卻是一個(gè)雙精度浮點(diǎn)數(shù)而非整數(shù)。因此為了確保讓ri綁定一個(gè)整數(shù),編譯器把上述代碼變成了如下形式:
const int temp=dval;//由雙精度浮點(diǎn)數(shù)生成一個(gè)臨時(shí)的整型常量 const int &ri=temp;//讓ri綁定這個(gè)臨時(shí)量
在這種情況下,ri綁定了一個(gè)臨時(shí)量對(duì)象。所謂臨時(shí)量對(duì)象就是當(dāng)編譯器需要一個(gè)空間來暫存表達(dá)式的求值結(jié)果時(shí)臨時(shí)創(chuàng)建的一個(gè)未命名的對(duì)象。C++程序員們常常把臨時(shí)量對(duì)象簡(jiǎn)稱為臨時(shí)量。
const與auto類型說明符
auto類型說明符是C++11中新引入的類型說明符,可以自動(dòng)推斷類型。
編譯器推斷出來的auto類型有時(shí)候和初始值的類型并不完全一樣,編譯器會(huì)適當(dāng)?shù)母淖兘Y(jié)果類型使其更符合初始化規(guī)則。
auto在推斷帶有const的對(duì)象時(shí),編譯器一般會(huì)忽略掉頂層const,同時(shí)底層const則會(huì)保留下來。 另外對(duì)于引用由于引用沒有真正的實(shí)體,所以如果用一個(gè)引用來初始化auto類型時(shí),auto實(shí)際上為引用所指向的對(duì)象的類型,而非引用,如果要說明其為引用類型,需要使用auto&。
const int ci=i,&cr=ci; auto b=ci;//b是一個(gè)整數(shù)(ci的頂層const特性被忽略掉了) auto c=cr;//c是一個(gè)整數(shù)(cr是ci的別名,ci本身是一個(gè)頂層const) auto d=&i;//d是一個(gè)整型指針(整數(shù)的地址就是指向整數(shù)的指針) auto e=&ci;//e是一個(gè)指向整數(shù)常量的指針(對(duì)常量對(duì)象取地址是一種底層const)
如果希望推斷出的auto類型是一個(gè)頂層const,需要明確指出:
const auto f=ci;//ci的推演類型為int,f是const int。
總結(jié)
以上所述是小編給大家介紹的C/C++中const限定符總結(jié),希望對(duì)大家有所幫助,也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
C++利用inotify+epoll實(shí)現(xiàn)異步文件監(jiān)控的方法
這篇文章講給大家詳細(xì)介紹一下C++利用inotify+epoll實(shí)現(xiàn)異步文件監(jiān)控的方法,inotify是一種異步文件監(jiān)控機(jī)制,文章通過代碼示例介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2023-08-08c++ 求數(shù)組最大最小值函數(shù)的實(shí)現(xiàn)
這篇文章主要介紹了c++ 求數(shù)組最大最小值函數(shù)的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07C++20 特性 協(xié)程 Coroutines(1)
這篇文章主要給大家分享得是C++20 得特性 協(xié)程 Coroutines,下面文章內(nèi)容我們將來具體介紹什么是協(xié)程,協(xié)程得好處等知識(shí)點(diǎn),需要的朋友可以參考一下2021-10-10如何判斷一個(gè)整數(shù)的二進(jìn)制中有多少個(gè)1
本篇文章是對(duì)如何判斷一個(gè)整數(shù)的二進(jìn)制中有多少個(gè)1的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05簡(jiǎn)單掌握桶排序算法及C++版的代碼實(shí)現(xiàn)
桶排序是將要排序的算法按桶分組排序之后再遍歷匯總的一種線性排序算法,下面就讓我們來通過小例子簡(jiǎn)單掌握桶排序算法及C++版的代碼實(shí)現(xiàn)^^2016-07-07C++如何動(dòng)態(tài)的生成對(duì)象詳解
C++是不支持根據(jù)類名動(dòng)態(tài)地生成對(duì)象的,比如從一個(gè)文本文件中讀取類名然后構(gòu)造一個(gè)對(duì)象.主要原因是沒有豐富的動(dòng)態(tài)元信息,沒有單根類庫。那么下面這篇文章就來給大家介紹C++是如何動(dòng)態(tài)的生成對(duì)象,有需要的朋友們可以參考借鑒。2017-02-02C++中vector容器的常用操作方法實(shí)例總結(jié)
vector容器一般被用作創(chuàng)建動(dòng)態(tài)數(shù)組,動(dòng)態(tài)數(shù)組就像Python中的list結(jié)構(gòu)一樣,可以比普通數(shù)組擁有更豐富操作方法,下面就為大家整理了一些最常用的操作:2016-05-05