前言

在《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