欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++中的const的使用詳解

 更新時(shí)間:2017年05月12日 08:41:44   投稿:lqh  
這篇文章主要介紹了 C++中的const的使用詳解的相關(guān)資料,需要的朋友可以參考下

const的基本使用

const的用法我覺(jué)得對(duì)于一個(gè)以后想著做一個(gè)優(yōu)秀的程序員來(lái)說(shuō),這是必須熟練掌握的技能。因?yàn)榫W(wǎng)上有好多的文章介紹它的寫(xiě)的非常好,有的我就直接拿過(guò)來(lái)了~,現(xiàn)在我們來(lái)看看他的用法。

const 要求他所修飾的對(duì)象為常量,不可被改變,不可被賦值,不可作為左值.

1、函數(shù)體內(nèi)修飾局部變量

例:

void func(){
const int a=0;
}

const作為一個(gè)類型限定詞,和int有相同的地位。

const int a; int const a;

是等價(jià)的。于是此處我們一定要清晰的明白,const修飾的對(duì)象是誰(shuí),是a還是int
const要求他所修飾的對(duì)象為常量,不可被改變,不可被賦值,不可作為左值(l-value)。所以很明顯它修飾的是a。這是一個(gè)很常見(jiàn)的使用方式:

const double pi=3.14;

在程序的后面如果企圖對(duì)pi再次賦值或者修改就會(huì)出錯(cuò)。然后看一個(gè)稍微復(fù)雜的例子。

const int* p;

因?yàn)閕nt* p;和 int *p;是等價(jià)的。
所以const int (*p)和int const (*p)是等價(jià)的?,F(xiàn)在一目了然const 修飾的是誰(shuí)? 是*p.所以p+=1;是合法的

*p+=1;是非法的因?yàn)閏onst修飾了你。

int* const p;那這個(gè)什么意思?

看const修飾的是什么? 它修飾的p。但是p是一個(gè)int型的指針,所以這個(gè)指針的地址沒(méi)有辦法修改。

p+=1; //這就是非法的
*p+=1; //這個(gè)是合法的

再看一個(gè)更復(fù)雜的例子,它是上面二者的綜合

const int* const p;說(shuō)明p自己是常量,且p指向的變量也是常量。
于是

p+=1; //非法
*p+=1; //非法

const 還有一個(gè)作用就是用于修飾常量靜態(tài)字符串。例如:

const char* name=David;

如果沒(méi)有const,我們可能會(huì)在后面有意無(wú)意的寫(xiě)name[4]='x'這樣的語(yǔ)句,這樣會(huì)導(dǎo)致對(duì)只讀內(nèi)存區(qū)域的賦值,然后程序會(huì)立刻異常終止。有了 const,這個(gè)錯(cuò)誤就能在程序被編譯的時(shí)候就立即檢查出來(lái),這就是const的好處。讓邏輯錯(cuò)誤在編譯期被發(fā)現(xiàn)。

2、在函數(shù)聲明時(shí)修飾參數(shù)
舉個(gè)例子void * myMemMove(void *dst,constvoid *src,intcount )這是我寫(xiě)的memmove函數(shù)的聲明,這個(gè)函數(shù)的意思就是(任意類型)把*src的內(nèi)容復(fù)制給*dst,我們現(xiàn)在很明顯的看到*src它只讓你復(fù)制,你不能修改它的值,所以怕你在以后的函數(shù)的定義里出現(xiàn)問(wèn)題現(xiàn)在在聲明里限制你。

3、全局變量
我們的原則依然是,盡可能少的使用全局變量。我們的第二條規(guī)則 則是,盡可能多的使用const。如果一個(gè)全局變量只在本文件中使用,那么用法和前面所說(shuō)的函數(shù)局部變量沒(méi)有什么區(qū)別。如果它要在多個(gè)文件間共享,那么就牽扯到一個(gè)存儲(chǔ)類型的問(wèn)題。

有兩種方式。

1.使用extern
例如
/* test.h */
extern const double pi;
/* test.c */
const double pi=3.14;

然后其他需要使用pi這個(gè)變量的,包含test.h

#include test.h

或者,自己把那句聲明復(fù)制一遍就好。

這樣做的結(jié)果是,整個(gè)程序鏈接完后,所有需要使用pi這個(gè)變量的共享一個(gè)存儲(chǔ)區(qū)域。

2.使用static,靜態(tài)外部存儲(chǔ)類

/* constant.h */
static const pi=3.14;

需要使用這個(gè)變量的*.c文件中,必須包含這個(gè)頭文件。

前面的static一定不能少。否則鏈接的時(shí)候會(huì)報(bào)告說(shuō)該變量被多次定義。這樣做的結(jié)果是,每個(gè)包含了constant.h的*.c文件,都有一份該變量自己的copy,該變量實(shí)際上還是被定義了多次,占用了多個(gè)存儲(chǔ)空間,不過(guò)在加了static關(guān)鍵字后,解決了文件間重定義的沖突。壞處是浪費(fèi)了存儲(chǔ)空間,導(dǎo)致鏈接完后的可執(zhí)行文件變大。但是通常,這個(gè),小小幾字節(jié)的變化,不是問(wèn)題。好處是,你不用關(guān)心這個(gè)變量是在哪個(gè)文件中被初始化的。
其實(shí)const我覺(jué)得更多是程序員自己限制自己,自己告訴自己后面哪里不能出現(xiàn)錯(cuò)誤

舉個(gè)例子吧。

#include<stdio.h>
#include<Windows.h>
int main()
{
	int *p;
	const int a = 0;
	p = &a;
	*p = 3;
	printf("a= %d \n", a);
	system("pause");
	return 0;
}

現(xiàn)在看看運(yùn)行結(jié)果

現(xiàn)在我要說(shuō)一個(gè)const操作里面的一些做法,

舉個(gè)例子我們以前寫(xiě)過(guò)的一個(gè)類,我們會(huì)使用operator[]來(lái)返回一個(gè)reference的指向,這個(gè)一般情況我們都會(huì)寫(xiě)一個(gè)

const的也會(huì)寫(xiě)一個(gè)非const的opeartor[].這是我們最常見(jiàn)的一個(gè)代碼:

T& operator[](int position) 
{ 
 return xxx[position]; 
} 
const T& operator[](int position) const 
{ 
 return xxx[position]; 
}

這是我們平時(shí)寫(xiě)的初級(jí)的代碼,但是現(xiàn)在當(dāng)我們要寫(xiě)一個(gè)TextBlock內(nèi)的opeartor[]不單只返回一個(gè)referencr了,也可能執(zhí)行邊界檢查,日志訪問(wèn)信息,還有什么數(shù)據(jù)完善性檢驗(yàn)等等一大堆繁瑣的代碼,這個(gè)時(shí)候當(dāng)你實(shí)現(xiàn)operator[] const和operator[]() const,的時(shí)候兩份代碼大部分都一樣,這里伴隨的是代碼重復(fù),編譯時(shí)間變長(zhǎng),維護(hù)代碼膨脹等等頭疼的問(wèn)題. 當(dāng)然啦,你可以讓上述那些繁瑣的函數(shù)全部封裝的別的函數(shù)中,然后分別在operator[]()和operator[]()const當(dāng)中調(diào)用但是你還說(shuō)重復(fù)了一些代碼比如兩次return語(yǔ)句,函數(shù)調(diào)用.真正該做的是實(shí)現(xiàn)operator[]的機(jī)能一次并使用它兩次。也就是你只需要寫(xiě)一個(gè)函數(shù),令另外一個(gè)調(diào)用這個(gè),這促使我們將常量性轉(zhuǎn)移. 接下來(lái) 見(jiàn)證奇跡我們來(lái)看看下面這個(gè)代碼是怎么實(shí)現(xiàn)的上述的操作的:

class TextBlock 
{ 
public: 
 ... 
 const char& operator[](std::size_t position) const 
 { 
 ... 
 ... 
 ... 
 return text[position]; 
 } 
 
 char& operator[](std::size_t position) 
 { 
 return const_cast<char&>(static_cast<const TextBlock&>(*this)[position]); 
 } 
};

來(lái)仔細(xì)看這個(gè)操作;return const_cast<char&>(static_cast<const TextBlock&>(*this)[position]);
首先把*this強(qiáng)制轉(zhuǎn)換為const TextBlock,再然后調(diào)用const的operator[],最后再把const的operator[]的返回值的const常量性取消,然后返回一個(gè)非const的值. 這里的調(diào)用實(shí)在是太妙了,我們可以思考一下,好好想想這里的深意.
但是會(huì)有人說(shuō),為什么不用const operator[]調(diào)用operator[]呢,這樣強(qiáng)制兩個(gè)都可以行的通啊.這樣想是錯(cuò)的!

令const版本調(diào)用調(diào)用no-const版本以避免重復(fù)并不是你該做的事情. 記住const所修飾函數(shù)的承諾就是我絕對(duì)不會(huì)修改你,no-const函數(shù)可沒(méi)有這種承諾,所以你讓一個(gè)const函數(shù)去調(diào)用一個(gè)no-const函數(shù)是不現(xiàn)實(shí)的. over其實(shí)const有很多可以玩的屬性,只要我們想到就可以去實(shí)現(xiàn),這里就說(shuō)這么一個(gè)就ok. 接下來(lái)我們來(lái)瞧瞧另外兩個(gè)關(guān)鍵字.

 C++中的const的使用詳解

const在c/c++中還是會(huì)經(jīng)常出現(xiàn)的,并且如果不理解const會(huì)在編程出現(xiàn)的錯(cuò)誤而不知所措,無(wú)法理解。下面從幾個(gè)角度簡(jiǎn)要理解const的內(nèi)容,應(yīng)該還是蠻有用的。

const與指針類型

const int*p = NULL; 和int const*p = NULL;是等價(jià)的。因?yàn)閏onst都在“ * ”的前面,其實(shí)是以*為標(biāo)志的。

1. int x = 3; const int *p = &x; 


// p = &y;正確 , //*p = 4;錯(cuò)誤 

指針其實(shí)一般是4個(gè)字節(jié)長(zhǎng)度。p的內(nèi)容是存儲(chǔ)0x….,就是其他數(shù)據(jù)的地址。因此這里的const修飾*p就是說(shuō):*p的內(nèi)容是不可直接被賦值改變的。

而p本身存儲(chǔ)的地址是可變的,可以變成其他的0x…..當(dāng)p指向其他的數(shù)據(jù)地址時(shí),*p也就隨之變成新的數(shù)據(jù)。

int x = 3; int *const p = &x; //p = &y是錯(cuò)誤的

總結(jié):其實(shí)是看這個(gè)const是在的前面還是后面,如果在的前面,則表示修飾的是整個(gè)“ p ”,而在后面,則表示修飾的是只有p。

顯然有:在前面,則表示整個(gè)*p是const的,因此p可以指向其他的地址,而*p則是const的,無(wú)法改變。同理,int *const p = &x;則表示指針p是固定的,就是說(shuō)p指針存儲(chǔ)的地址是固定的,其內(nèi)容是const,因此無(wú)法修改為其他值(即指向其他地址)。

const與引用

int x = 3; const int &y = x; 
//x = 10;正確 //y = 20; 錯(cuò)誤 

引用前面有const,所以不能通過(guò)y來(lái)修改x的值。

本人的理解:const int &y就是相當(dāng)于const int *y1 = &x;然后y = 20就相當(dāng)于*y1 = 20;這顯然時(shí)不允許的(就如前面所說(shuō)的,*p時(shí)const,無(wú)法直接賦值給*p)。因?yàn)橐镁拖喈?dāng)于給x取了一個(gè)別名y,此時(shí)y不就是y1指針?biāo)傅膬?nèi)容嗎?也就是說(shuō)上面的例子:y = 20;就是相當(dāng)于 *y1 = 20.

錯(cuò)誤的const使用

其他:const int x = 3; int *y = &x; 不能通過(guò)編譯。因?yàn)榭赡芡ㄟ^(guò)*p修改本應(yīng)該是const的x;
int x = 3; const int *y = &x; 這是可以的,這里的x是可變的,通過(guò)由于*y是const的,因此*y就是只能是讀取x的值,而不具有寫(xiě)入x的權(quán)利。

總結(jié):可以說(shuō)是只能把一個(gè)東西權(quán)限縮小,而不能使其原始的權(quán)限增大。

const在函數(shù)中的應(yīng)用

主要是防止函數(shù)的誤操作,對(duì)值進(jìn)行更改

void fun(const int&a, const int&b) 
{ 
//這里就不能對(duì)a或b進(jìn)行更改,否則會(huì)編譯出錯(cuò) 
}

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

相關(guān)文章

最新評(píng)論