首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C++ const 關鍵字完整指南:從基礎宣告到類別成員、函式參數與強制轉型

     編輯:關於C語言

const 是 C++ 型別系統的基石,正確使用能讓編譯器協助發現邏輯錯誤、優化程式碼、表達設計意圖。本文涵蓋基本宣告、指標與常量指標、函式參數/回傳值、類別成員、mutable 與 const_cast 進階用法,並釐清常見誤區。

一、基本宣告與初始化


const int MAX = 100;           // 編譯期常數,內部連結(C++),建議替代 #define
extern const int GLOBAL_MAX;   // 外部連結,跨檔共用,需在 .cpp 定義
const int arr[] = {1,2,3};     // 常數陣列,編譯器配置記憶體,不可作為編譯期常數運算

⚠️ const int const* p:對 int 重複套用 const,編譯器警告 C4114。

二、指標與 const 的四種組合

宣告口訣指標可改向指向值可修改別名
const int* p
int const* p
指向 const 的指標✅❌Pointer to Const
int* const pconst 指標❌✅Const Pointer
const int* const p指向 const 的 const 指標❌❌Const Pointer to Const

💡 記憶法:**從右向左讀**,const 修飾其右側緊鄰元素。

三、函式參數與回傳值

1. 值傳遞加 const:無意義


void Func(const int x); // x 本身就是副本,const 只是防止函式內修改參數變數,對呼叫端無影響

2. 參考/指標傳遞加 const:核心用法


void ReadOnly(const BigObj& obj);      // 避免拷貝,承諾不修改
void ReadOnlyPtr(const BigObj* ptr);   // 同樣語意
// 唯有 const 參考能綁定暫時物件
void Func(const string& s);
Func("temp"); // ✅ 合法,延長暫時物件生命週期
// Func(string& s); Func("temp"); // ❌ 非 const 參考不可綁定暫時物件

3. 回傳值加 const

  • 內建型別回傳 const int 無意義(回傳的是右值,不可修改)。
  • 使用者定義型別回傳 const Class 禁止左值操作:Func() = obj; 編譯錯誤,防止 GetObj().Modify() 修改暫時物件。

4. 指標回傳的 const 層次


const char* Func1();        // 回傳指向 const char 的指標,呼叫端不可修改內容
char* const Func2();        // 回傳 const 指標(指標本身不可修改),極少用
const char* const Func3();  // 雙重 const,回傳 const 指標指向 const 資料

四、類別中的 const

1. const 資料成員

  • 只能在建構函式成員初始化列表初始化:Class(int v): m_constVal(v) {}。
  • 靜態 static const int 整數型別可在類別內初始化(C++11 起所有字面型別皆可)。

2. const 成員函式


class Widget {
    int m_val;
    mutable int m_cacheHits; // 可在 const 函式修改
public:
    int GetVal() const { ++m_cacheHits; return m_val; } // ✅ 承諾不修改邏輯狀態
    void SetVal(int v) { m_val = v; } // 非 const
};
const Widget cw;
cw.GetVal(); // ✅
// cw.SetVal(1); // ❌ 編譯錯誤
  • const 放在參數列表後:RetType Func(params) const。
  • 編譯器強制檢查:函式內不可修改非 mutable 成員、不可呼叫非 const 成員函式。
  • mutable:標記「邏輯上不影響物件可觀測狀態」的成員(快取、鎖、統計計數)。

3. 建構/解構函式不可為 const

建構時物件尚未形成「常態」,解構時需修改資源釋放狀態。

五、const_cast:移除 const 屬性(慎用!)


const int CI = 100;
int* p = const_cast(&CI); // C++ 風格
// *p = 200; // ⚠️ 未定義行為!原物件為真正 const,修改導致 UB
  • 唯一合法用途:呼叫非 const 正確的舊式 API,且確知該 API 不會修改物件。
  • 修改原本定義為 const 的物件屬於未定義行為(編譯器可能將其放入唯讀段、常數摺疊等)。

六、字串字面常數陷阱


char* s1 = "hello";  // ❌ C++11 起棄用,字串字面值為 const char[]
const char* s2 = "hello"; // ✅ 正確
char s3[] = "hello"; // ✅ 陣列複製,可修改 s3[0]='H'

最佳實踐速查

  • ✅ 所有不修改參數的指標/參考參數**一律加 const**。
  • ✅ 所有不修改 this 的成員函式**一律加 const**。
  • ✅ 回傳指標/參考時,若不希望呼叫端修改,**加 const**。
  • ✅ 善用 mutable 區分「邏輯常態」與「實體常態」。
  • ❌ 絕不使用 const_cast 修改真正的常數物件。
  • ❌ 不要對值傳遞參數加 const(無意義且誤導)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved