C++ const的各種用法詳解
C++作為一種面向?qū)ο蟮慕?jīng)典語言,它是非常的強(qiáng)大,它的每個部分都值得我們?nèi)ド钊肓私狻?/p>
const的基本概念:
const名叫常量限定符,用來限定特定變量,以通知編譯器該變量是不可修改的。習(xí)慣性的使用const,可以避免在函數(shù)中對某些不應(yīng)修改的變量造成可能的改動。
下面我就const的用法來談?wù)劊?/p>
const的用法大致可分為以下幾個方面:
(1)const修飾基本數(shù)據(jù)類型
(2)const應(yīng)用到函數(shù)中
(3)const在類中的用法
(4)const修飾類對象,定義常量對象
一、const修飾基本數(shù)據(jù)類型
1.const修飾一般常量及數(shù)組
const int a=10; 等價的書寫方式: int const a=10; const int arr[3]={1,2,3}; int const arr[3]={1,2,3};
對于類似這些基本數(shù)據(jù)類型,修飾符const可以用在類型說明符前,也可以用在類型說明符后,其結(jié)果是一樣的。在使用這些常量的時候,只要不改變這些常量的值便好。
2.const修飾指針變量*及引用變量&
介紹本部分內(nèi)容之前,先說說指針和引用的一些基本知識。
指針(pointer)是用來指向?qū)嶋H內(nèi)存地址的變量,一般來說,指針是整型,而且一般的大家會接受十六進(jìn)制的輸出格式。
引用(reference)是其相應(yīng)變量的別名,用于向函數(shù)提供直接訪問參數(shù)(而不是參數(shù)的副本)的途徑,與指針相比,引用是一種受限制的指針類型,或者說是指針的一個子集,而從其功能上來看,似乎可以說引用是指針功能的一種高層實(shí)現(xiàn)。
關(guān)于運(yùn)算符&和*:
在C++里,沿襲C中的語法,有兩個一元運(yùn)算符用于指針操作:&和*。按照本來的定義,&應(yīng)當(dāng)是取址符,*是指針符,也就是說, &用于返回變量的實(shí)際地址,*用于返回地址所指向的變量,他們應(yīng)當(dāng)互為逆運(yùn)算。實(shí)際的情況也是如此。
在定義變量的引用的時候,&只是個定義引用的標(biāo)志,不代表取地址。
舉例:
#include<iostream.h> void main() { int a; //a is an integer int *aPtr; //aPtr is a pointer to an integer a=7; aPtr = &a; cout<<"Showing that * and & are inverses of "<<"each other.\n"; cout<<"a="<<a<<" *aPtr="<<*aPtr<<"\n"; cout<<"&*aPtr = "<<&*aPtr<<endl; cout<<"*&aPtr = "<<*&aPtr <<endl; }
運(yùn)行結(jié)果:
了解完指針和應(yīng)用的基本概念之后,下面繼續(xù)我們的話題。
const修飾指針(*):
const int* a = & [1] //非常量數(shù)據(jù)的常量指針 指針常量 int const *a = & [2] //非常量數(shù)據(jù)的常量指針 a is a pointer to the constant char variable int* const a = & [3] //常量數(shù)據(jù)的非常量指針指針常量 常量指針 a is a constant pointer to the (non-constant) char variable const int* const a = & [4] //常量數(shù)據(jù)的常量指針
可以參考《Effective c++》Item21上的做法,
如果const位于星號*的左側(cè),則const就是用來修飾指針?biāo)赶虻淖兞?,即指針指向?yàn)槌A浚?/p>
如果const位于星號的右側(cè),const就是修飾指針本身,即指針本身是常量。
因此,[1]和[2]的情況相同,都是指針?biāo)赶虻膬?nèi)容為常量,這種情況下不允許對內(nèi)容進(jìn)行更改操作,如不能*a = 3 ;
[3]為指針本身是常量,而指針?biāo)赶虻膬?nèi)容不是常量,這種情況下不能對指針本身進(jìn)行更改操作,如a++是錯誤的;
[4]為指針本身和指向的內(nèi)容均為常量。
const修飾引用(&):
int const &a=x; const int &a=x; int &const a=x;//這種方式定義是C、C++編譯器未定義,雖然不會報錯,但是該句效果和int &a一樣。
這兩種定義方式是等價的,此時的引用a不能被更新。如:a++ 這是錯誤的。
二、const應(yīng)用到函數(shù)中
1.作為參數(shù)的const修飾符
2.作為函數(shù)返回值的const修飾符
其實(shí),不論是參數(shù)還是返回值,道理都是一樣的,參數(shù)傳入時候和函數(shù)返回的時候,初始化const變量
1修飾參數(shù)的const,如 void fun0(const A* a ); void fun1(const A& a);
調(diào)用函數(shù)的時候,用相應(yīng)的變量初始化const常量,則在函數(shù)體中,按照const所修飾的部分進(jìn)行常量化,如形參為const A* a,
則不能對傳遞進(jìn)來的指針的內(nèi)容 進(jìn)行改變,保護(hù)了原指針?biāo)赶虻膬?nèi)容;如形參為const A& a,則不能對傳遞進(jìn)來的引用對象進(jìn)行改變,
保護(hù)了原對象的屬性。
[注意]:參數(shù)const通常用于參數(shù)為指針或引用的情況;
2修飾返回值的const,如const A fun2( ); const A* fun3( );
這樣聲明了返回值后,const按照"修飾原則"進(jìn)行修飾,起到相應(yīng)的保護(hù)作用。
const Rational operator*(const Rational& lhs, const Rational& rhs)
{
return Rational(lhs.numerator() * rhs.numerator(),
lhs.denominator() * rhs.denominator());
}
返回值用const修飾可以防止允許這樣的操作發(fā)生:
Rational a,b;
Radional c;
(a*b) = c;
一般用const修飾返回值為對象本身(非引用和指針)的情況多用于二目操作符重載函數(shù)并產(chǎn)生新對象的時候。
類中的成員函數(shù):A fun4()const; 其意義上是不能修改所在類的的任何變量。
三、類中定義常量(const的特殊用法)
在類中實(shí)現(xiàn)常量的定義大致有這么幾種方式實(shí)現(xiàn):
1.使用枚舉類型
class test { enum { SIZE1 = 10, SIZE2 = 20}; // 枚舉常量 int array1[SIZE1]; int array2[SIZE2]; };
2.使用const
不能在類聲明中初始化const數(shù)據(jù)成員。以下用法是錯誤的,因?yàn)轭惖膶ο笪幢粍?chuàng)建時,編譯器不知道SIZE的值是什么。
class test { const int SIZE = 100; // 錯誤,企圖在類聲明中初始化const數(shù)據(jù)成員 int array[SIZE]; // 錯誤,未知的SIZE };
正確的使用const實(shí)現(xiàn)方法為:const數(shù)據(jù)成員的初始化只能在類構(gòu)造函數(shù)的初始化表中進(jìn)行。
class A {… A(int size); // 構(gòu)造函數(shù) const int SIZE ; }; A::A(int size) : SIZE(size) // 構(gòu)造函數(shù)的初始化表 { … } //error 賦值的方式是不行的 A::A(int size) { SIZE=size; } void main() { A a(100); // 對象 a 的SIZE值為100 A b(200); // 對象 b 的SIZE值為200 }
注意:對const成員變量的初始化,不能在變量聲明的地方,必須在類的構(gòu)造函數(shù)的初始化列表中完成,即使是在構(gòu)造函數(shù)內(nèi)部賦值也是不行的。
具體原因請參見 【初始化列表和賦值的區(qū)別】
3.使用static const
通過結(jié)合靜態(tài)變量來實(shí)現(xiàn):
#include<iostream.h> class Year { private: int y; public: static int const Inity; public: Year() { y=Inity; } }; int const Year::Inity=1997;//靜態(tài)變量的賦值方法,注意必須放在類外定義 void main() { cout<<Year.Inity<<endl;//注意調(diào)用方式,這里是用類名調(diào)用的。 }
到這里就把在類中定義常量的方法都陳列出來了。
四、const定義常量對象,以及常量對象的用法
class test { public: test():x(1) { y=2; } ~test() {} void set(int yy) { y=yy; } int getx() const { return x; } //protected: const int x; int y; }; void main() { const test t; t.set(33);//error t.getx(); }
常量對象只能調(diào)用常量函數(shù),別的成員函數(shù)都不能調(diào)用。
五、使用const的一些建議
<1>要大膽的使用const,這將給你帶來無盡的益處,但前提是你必須搞清楚原委;
<2> 要避免最一般的賦值操作錯誤,如將const變量賦值,具體可見思考題;
<3> 在參數(shù)中使用const應(yīng)該使用引用或指針,而不是一般的對象實(shí)例,原因同上;
<4> const在成員函數(shù)中的三種用法(參數(shù)、返回值、函數(shù))要很好的使用;
<5>不要輕易的將函數(shù)的返回值類型定為const;
<6>除了重載操作符外一般不要將返回值類型定為對某個對象的const引用;
參考資料:
(1)繼續(xù)C++——指針,引用和常量限定符const
http://blog.csdn.net/jarodwen/archive/2006/12/19/1449568.aspx
(2)C++中const用法總結(jié)
http://lanmh.iteye.com/blog/796410
(3)常量函數(shù)、常量引用參數(shù)、常量引用返回值[C++]
http://www.cnblogs.com/JCSU/articles/1045801.html
(4)const使用詳解
http://www.vckbase.com/document/viewdoc/?id=412
(5)c/c++中const用法總結(jié)
http://www.newsmth.net/pc/pccon.php?id=10002714&nid=359712
(6)高質(zhì)量C++/C編程指南 http://fanqiang.chinaunix.net/a4/b2/20020717/060200270.html
(7) Effective C++筆記—構(gòu)造函數(shù)賦值VS初始化列表 http://blog.csdn.net/lifeisbetter/archive/2009/12/29/5099085.aspx
(8)初始化列表與構(gòu)造函數(shù)內(nèi)賦值
以上就是C++ const的各種用法詳解的詳細(xì)內(nèi)容,更多關(guān)于C++ const用法的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++實(shí)現(xiàn)關(guān)系與關(guān)系矩陣的代碼詳解
這篇文章主要介紹了C++實(shí)現(xiàn)關(guān)系與關(guān)系矩陣,功能實(shí)現(xiàn)包括關(guān)系的矩陣表示,關(guān)系的性質(zhì)判斷及關(guān)系的合成,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-04-04C++實(shí)現(xiàn)編碼轉(zhuǎn)換的示例代碼
這篇文章主要介紹了C++實(shí)現(xiàn)編碼轉(zhuǎn)換的示例代碼,幫助大家快捷的實(shí)現(xiàn)編碼轉(zhuǎn)換,感興趣的朋友可以了解下2020-08-08C++?分割字符串?dāng)?shù)據(jù)的實(shí)現(xiàn)方法
這篇文章主要介紹了C++?分割字符串?dāng)?shù)據(jù)的實(shí)現(xiàn)方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09源碼分析C++是如何實(shí)現(xiàn)string的
我們平時使用C++開發(fā)過程中或多或少都會使用std::string,但您了解string具體是如何實(shí)現(xiàn)的嗎,本文小編就帶大家從源碼角度分析一下2023-04-04