C/C++ const 的 3 種用法與範例

本篇 ShengYu 介紹 C/C++ const 的 3 種用法與範例,包含 C++ const 平常的一般基本用法以及 C++ const 在成員函式中的用法。

以下 C/C++ const 的用法介紹分別為這幾種,

  • C/C++ const 加上變數前的用法
  • C++ const 加在成員函式前面的用法
  • C++ const 加在成員函式後面的用法

那我們開始吧!

C/C++ const 加上變數前的用法

這邊介紹 C/C++ const 加上變數前的用法,C/C++ const 加上變數前表示不能修改該變數,該變數為 read-only,

如下範例所示,宣告 const int n = 5; 之後如果嘗試對 n 進行修改的話會得到 error: assignment of read-only variable ‘n’ 編譯錯誤訊息,

1
2
3
4
5
6
7
8
#include <iostream>
using namespace std;

int main() {
const int n = 5;
//n = 10; // compile error
return 0;
}

這邊要另外舉個字串指標的例子,const char *str 雖然是不能修改其 str 指標指向的內容,但 str 指標本身卻是可以修改的,所以這部份在使用上需要特別注意,詳細說明如下,

如下例所示,宣告一個 const char * name2 = "Amy";,name2 表示指標指向的內容不可修改,如果嘗試對 name2 指標指向的內容進行修改的話會得到 error: assignment of read-only location ‘* name2’ 編譯錯誤,例如下例中的 name2[0] = 'B'; 就是對 name2 指向的內容進行修改,

但是 name2 指標本身是可以修改的,也就是可以修改 name2 指標指向別的地方,如下例中的 name2 = name; 將 name2 指向 name,這樣 name2 印出來的內容就會是 Tom 而不是 Amy,

如果要指標本身不可修改的話,可以像下中的 name3 前加上 const 變成 const char * const name3,這樣就是表示指標本身不可修改且指向的內容也不可修改,之後如果嘗試對 name3 的指標進行修改的話會得到 error: assignment of read-only variable ‘name3’ 編譯錯誤訊息,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>
using namespace std;

int main() {
char name[5] = "Tom";
cout << name << "\n";

const char * name2 = "Amy";
//name2[0] = 'B'; // compile error, 不可修改 name2 指向的內容
name2 = name; // 可以修改 name2 指標
cout << name2 << "\n";

const char * const name3 = "Amy";
//name3 = name; // compile error, 不可修改 name3 指標本身

return 0;
}

結果輸出如下,

1
2
Tom
Tom

如果換成整數指標的話就可能有這幾種情況,

1
2
3
4
const int * a = &b; // 指標指向的內容不可改變
int const * a = &b; // 同上
int * const a = &b; // 常數指標,即指標本身的值是不可改變的,但指向的內容是可改變的
const int * const a = &b; // 指向常數的常數指標,即指標本身與指向的內容都是不可改變的

綜合上述指標加上 const 的用法大致分成兩種情況,一種就是不可修改的指標,另一種則是指標指向的內容(記憶體區塊)不可修改,
不可修改的指標:即指標不可修改,代表該指標永遠指向某塊記憶體位置
指標指向的內容(記憶體區塊)不可修改:即指標指向的記憶體區塊不能修改,只能讀取 read-only

C++ const 加在成員函式前面的用法

在 C++ 中有時候希望回傳的東西不能被修改的話,這時就可以使用 const 加在成員函式前面來達成這個目的,我們來看看下面這個例子,

在 main 函式裡要取得 s.getName() 成員函式回傳的變數話需要宣告一個 const std::string& studentName,由於 studentName 是 const 的關係所以之後我們就只能對這個變數作讀取不能修改值,如果嘗試對 studentName 進行修改的話會得到編譯錯誤,

因為 studentName 是 reference 參考的關係,所以之後使用 s.setName("Tom") 改變了 s 物件裡的 name 後,之後 studentName 裡面的值也會跟著改變,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <string>

class Student {
public:
Student() {}

const std::string& getName() {
return name;
}

void setName(std::string name) {
this->name = name;
}

private:
std::string name = "unknown";
};

int main() {
Student s;
const std::string& studentName = s.getName();
std::cout << studentName << "\n";
// studentName = "Tom"; compile error
s.setName("Tom");
std::cout << studentName << "\n";
return 0;
}

結果輸出如下,

1
2
unknown
Tom

再舉個 STL 容器的例子,使用 std::queue 容器 將 1、2、3 元素推入後,之後使用 front() 取得頭部元素,這時我們只是需要把變數 n 印出來而已,所以不會對它進行修改,如果嘗試對 const int &n 修改的話會得到編譯錯誤的 error: cannot assign to variable 'n' with const-qualified type 'const int &' 訊息,

另外宣告 int &n2 = q.front(); 參考的方式來修改 queue 頭部元素,之後 n 裡面的數值也會跟著改變,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <queue>

int main() {
std::queue<int> q;
q.push(1);
q.push(2);
q.push(3);
const int &n = q.front();
// n = 5; compile error
std::cout << n << "\n";

int &n2 = q.front();
n2 = 4;
std::cout << n << "\n";
return 0;
}

輸出結果如下,

1
2
1
4

C++ const 加在成員函式後面的用法

這邊介紹 C++ const 加在成員函式後面的用法,const 加在成員函式後面表示不能在該成員函式裡修改類別成員變數,因為該函式裡的存取類別成員都會是 read-only,範例如下,

如果在 getCounter() 成員函式裡嘗試對 counter 進行修改會得到編譯錯誤(error: increment of member ‘Object::counter’ in read-only object),對其它類別成員 number 修改也是會得到編譯錯誤(error: assignment of member ‘Object::number’ in read-only object),但是對 getCounter() 裡宣告的 number2 區域變數可以進行修改,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
using namespace std;

class Object {
public:
Object() {}

int getCounter() const {
//counter++; // compile error, const 加在成員函式後面表示不行在該函式裡修改成員變數
//number = 10; // compile error, const 加在成員函式後面表示不行在該函式裡修改成員變數
int number2;
number2 = 10; // 區域變數可以進行修改
return counter;
}

void addCount() {
counter++;
}

private:
int counter = 0;
int number = 0;
};

int main() {
Object o;
int counter = o.getCounter();
std::cout << counter << "\n";
o.addCount();
std::cout << counter << "\n";

int counter2 = o.getCounter();
std::cout << counter2 << "\n";
return 0;
}

以上就是 C/C++ const 的 3 種用法與範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
https://welkinchen.pixnet.net/blog/post/48176548
https://docs.microsoft.com/zh-tw/cpp/cpp/const-cpp?view=msvc-170
https://blog.xuite.net/coolflame/code/16605512

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ static 的 5 種用法
C/C++ extern 用法與範例
C/C++ call by value傳值, call by pointer傳址, call by reference傳參考 的差別