關於
c++中的
const
關鍵字的用法非常靈活,而使用
const
將大大改善程式的健壯性,現將本人的一些體會總結如下,期望對大家有所幫助:
一const
基礎如果
const
關鍵字不涉及到指標,我們很好理解,下面是涉及到指標的情況:
int b = 500;
const int* a = &b; [1]
int const *a = &b; [2]
int* const a = &b; [3]
const int* const a = &b; [4]
如果你能區分出上述四種情況,那麼,恭喜你,你已經邁出了可喜的一步。不知道,也沒關係,我們可以參考《
effective c++
》item21
上的做法,如果
const
位於星號的左側,則
const
就是用來修飾指標所指向的變數,即指標指向為常量;如果
const
位於星號的右側,
const
就是修飾指標本身,即指標本身是常量。因此,
[1]和
[2]的情況相同,都是指標所指向的內容為常量(
const
放在變數宣告符的位置無關),這種情況下不允許對內容進行更改操作,
如不能*a = 3
;[3]
為指標本身是常量,而指標所指向的內容不是常量,這種情況下不能對指標本身進行更改操作
,如a++
是錯誤的;
[4]為指標本身和指向的內容均為常量。
另外const
的一些強大的功能在於它在函式宣告中的應用。在乙個函式宣告中,
const
可以修飾函式的返回值,或某個引數;對於成員函式,還可以修飾是整個函式。有如下幾種情況,以下會逐漸的說明用法:
a& operator=(const a& a);
void fun0(const a* a );
void fun1( ) const; // fun1( )
為類成員函式
const a fun2( );
二const
的初始化
先看一下
const
變數初始化的情況
1) 非指標
const
常量初始化的情況:
a b;
const a a = b;
2) 指標(引用
)const
常量初始化的情況:
a* d = new a();
const a* c = d;
或者:const a* c = new a();
引用:a f;
const a& e = f; //
這樣作e
只能訪問宣告為
const
的函式,而不能訪問一般的成員函式;[思考
1]:以下的這種賦值方法正確嗎?
const a* c=new a();
a* e = c;[思考
2]:以下的這種賦值方法正確嗎?
a* const c = new a();
a* b = c;
三作為引數和返回值的
const
修飾符其實,不論是引數還是返回值,道理都是一樣的,引數傳入時候和函式返回的時候,初始化
const
變數1
修飾引數的
const
,如void fun0(const a* a ); void fun1(const a& a);
呼叫函式的時候,用相應的變數初始化
const
常量,則在函式體中,按照
const
所修飾的部分進行常量化,如形參為
const a* a
,則不能對傳遞進來的指標的內容進行改變,保護了原指標所指向的內容;如形參為
const a& a
,則不能對傳遞進來的引用物件進行改變,保護了原物件的屬性。[注意
]:引數
const
通常用於引數為指標或引用的情況;2
修飾返回值的
const
,如const a fun2( ); const a* fun3( );
這樣宣告了返回值後,
const按照"
修飾原則
"進行修飾,起到相應的保護作用。
const rational operator*(const rational& lhs, const rational& rhs)
返回值用
const
修飾可以防止允許這樣的操作發生
:rational a,b;
radional c;
(a*b) = c;
一般用const
修飾返回值為物件本身(非引用和指標)的情況多用於二目操作符過載函式並產生新物件的時候。[總結
] 一般情況下,函式的返回值為某個物件時,如果將其宣告為
const
時,多用於操作符的過載。通常,不建議用
const
修飾函式的返回值型別為某個物件或對某個物件引用的情況。
原因如下:
如果返回值為某個物件為
const
(const a test = a
例項)或某個物件的引用為
const
(const a& test = a
例項),則返回值具有
const
屬性,則返回例項只能訪問類
a中的公有(保護)資料成員和
const
成員函式,並且不允許對其進行賦值操作,這在一般情況下很少用到。[思考
3]:這樣定義賦值操作符過載函式可以嗎?
const a& operator=(const a& a);
四類成員函式中
const
的使用一般放在函式體後,形如:
void fun() const;
總結]
一般情況下,函式的返回值為某個物件時,如果將其宣告為
const
時,多用於操作符的過載。通常,不建議用
const
修飾函式的返回值型別為某個物件或對某個物件引用的情況。
原因如下:
如果返回值為某個物件為
const
(const a test = a
例項)或某個物件的引用為
const
(const a& test = a
例項),則返回值具有
const
屬性,則返回例項只能訪問類
a中的公有(保護)資料成員和
const
成員函式,並且不允許對其進行賦值操作,這在一般情況下很少用到。[思考
3]:這樣定義賦值操作符過載函式可以嗎?
const a& operator=(const a& a);
四類成員函式中
const
的使用一般放在函式體後,形如:
void fun() const;
如果乙個成員函式的不會修改資料成員,那麼最好將其宣告為
const
,因為const
成員函式中不允許對資料成員進行修改,如果修改,編譯器將報錯,這大大提高了程式的健壯性。五使用
const
的一些建議
1.要大膽的使用
const
,這將給你帶來無盡的益處,但前提是你必須搞清楚原委;
2.要避免最一般的賦值操作錯誤,如將
const
變數賦值,具體可見思考題;
3.在引數中使用
const
應該使用引用或指標,而不是一般的物件例項,原因同上;
4.const
在成員函式中的三種用法(引數、返回值、函式)要很好的使用;
5.不要輕易的將函式的返回值型別定為
const;
6.除了過載操作符外一般不要將返回值型別定為對某個物件的
const引用;
[思考題答案]1
這種方法不正確,因為宣告指標的目的是為了對其指向的內容進行改變,而宣告的指標
e指向的是乙個常量,所以不正確;
2 這種方法正確,因為宣告指標所指向的內容可變;
3 這種做法不正確;
在const a::operator=(const a& a)
中,引數列表中的
const
的用法正確,而當這樣連續賦值的時侯,問題就出現了:
a a,b,c:
(a=b)=c;
因為a.operator=(b)
的返回值是對a的
const
引用,不能再將
c賦值給
const
常量。
const用法詳解
物件導向是c 的重要特性.但是c 在c的基礎上新增加的幾點優化也是很耀眼的 就const直接可以取代c中的 define 以下幾點很重要,學不好後果也也很嚴重 1.const常量,如const int max 100 優點 const常量有資料型別,而巨集常量沒有資料型別。編譯器可以對前者進行型別安...
const 用法詳解
物件導向是c 的重要特性.但是c 在c的基礎上新增加的幾點優化也是很耀眼的 就const直接可以取代c中的 define 以下幾點很重要,學不好後果也也很嚴重 1.const常量,如const int max 100 優點 const常量有資料型別,而巨集常量沒有資料型別。編譯器可以對前者進行型別安...
const用法詳解
看 到const 關鍵字,很多人想到的可能是 const 常量,其實關鍵字 const 並不能把變數變成常量!在乙個符號前加上 const 限定符只是表示這個符號 不能被賦值。也就是它的值對於這個符號來說是唯讀的,但它並不能防止通過程式的內部 甚至是外部 的方法來修改這個值 c專家程式設計 p21 ...