前言
在《const關鍵字到底該怎麼用》一文中介紹了C語言中的const關鍵字,本文說說C++中的const關鍵字,它的大部分特點和C語言中的類似,所以本文主要針對不同之處。
修飾普通變數--只讀
在C語言,雖然表面是不允許被修改,但是看下面的程式碼:
#include
int main(void)
{
const int a = 10;
int *p = &a;
*p = 11;
printf(“a=%d\n”,a);
return 0;
}
它的輸出結果是
a=11
所以C語言裡,表面上它是隻讀的,然而你違規操作仍然能改變。但是,千萬不要寫這樣的程式碼!!!與C語言中const關鍵字不同的是,C++中使用const關鍵字定義的b變數的值在被改變時會被檢測。
看一個例子就明白了:
#include
int main()
{
const int a = 10;
int *p = &a;
*p = 11;
return 0;
}
編譯報錯如下:
main。cpp: In function ‘int main()’:
main。cpp:5:14: error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
int *p = &a;
再次強調:在實際中千萬不要寫這樣的程式碼,這裡只是為了說明問題。另外它們的作用也是一樣的,宣告一個只讀變數,不希望被修改,一旦被修改,編譯器將會報錯。但是你執行下面的程式碼,又會有驚喜:
#include
void test(const char* str)
{
char *p = (char*)str;
p[0] = ‘2’;
}
int main(void)
{
char a[] = “12345”;
test(a);
return 0;
}
畢竟未定義行為常常有驚喜。
我們常常看到傳遞const char*引數,像這樣:
void test(const char* str);
卻似乎從來沒有見到過const int作為引數的函式:
void test(const int val);
為何?因為前者傳遞指標的副本,指標指向不會被改變,但可以改變指向的內容;但是int型別引數,它也是傳遞副本,但是永遠不會被函式改變,自然也沒有必要加const關鍵字。更多解釋可以參考《傳值和傳指標》。同樣的,修飾函式返回值時,修飾內建型別與不加const修飾是一樣的,但對於自定義型別,不能對返回值進行修改,即返回的是常量。
作用在成員函式-不改變成員變數
舉個例子:
#include
class Test
{
private:
int a;
public:
void printA() const
{
a = 10;
}
};
int main()
{
Test test;
test。printA();
return 0;
}
類test中有一個成員變數a,並且有一個成員函式printA,現在假設你的設計是printA函式不會改變任何成員變數,那麼你可以在printA函式後加上const關鍵字,這樣一旦函內部嘗試修改成員變數,都會報錯:
main。cpp: In member function ‘void Test::printA() const’:
main。cpp:9:13: error: assignment of member ‘Test::a’ in read-only object
a = 10;
正因如此,const修飾成員函式不與static關鍵字同用,因為static修飾的靜態成員函式不能例項化,也就沒有例項的成員變數一說,自然不存在修改成員變數。
即下面的宣告是非法的:
static void printA() const
修飾類成員變數--建構函式中初始化
與修飾普通變數不同的是,修飾類成員變數還可以在建構函式中初始化。如:
#include
class Test
{
private:
const int a;
public:
Test(int val):a(val){}
};
int main()
{
Test test(1);
return 0;
}
修飾引用
例如,有一個常量
const int a = 10;
你不能再這樣定義它的引用:
int &ref = a;
而需要定義對常量的引用,即:
const int &ref = a;
為什麼呢?因為不能直接為a賦值,也不能間接賦值,所以自然不能定義普通引用去間接改變它。
總結
關於const關鍵字在C和C++中的區別,想必到這裡你已經清楚了。const關鍵字通常能借助編譯器幫助我們提前發現一些不易察覺的問題。如果你對下面的問題還不清楚,建議閱讀《const關鍵字到底該怎麼用》你能分清下面的宣告區別嗎?
const int *p;
int * const p;
int const * const p;
推薦閱讀:
作為一個C/C++工程師,聊聊對Python的看法
這樣的提問開頭建議你別用
幾道C/C++小題,看看你會不會
想了想,還是把私藏的精品書單分享給你們!
關注公眾號【程式設計珠璣】,獲取更多Linux/C/C++/演算法/計算機基礎/工具等原創技術文章。後臺免費獲取經典電子書和影片資源
來源:公眾號【程式設計珠璣】作者:守望先生ID:shouwangxiansheng