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

C++ const 關鍵字完全指南:從基礎用法到進階應用

     編輯:關於C語言

前言

const 是 C++ 中最重要、用途最廣的關鍵字之一。它不僅用於定義常量,更是實現「只讀語義」、提升代碼安全性、啟用編譯器優化的關鍵工具。本文系統梳理 const 的七大核心用法場景。

1. 定義編譯期常量:替代 #define

const double PI = 3.1415926; // 類型安全、有作用域、可調試

相比 #define PI 3.1415926,const 變量:

  • 具有類型,編譯器進行類型檢查
  • 有作用域,避免全局命名污染
  • 可在調試器中查看值
  • 支持用戶定義類型

2. 類的非靜態 const 成員:每個對象擁有自己的常量值


class Test {
private:
    const int m_i; // 必須在初始化列表中初始化
public:
    Test(int ii) : m_i(ii) {} // 只能在這裡初始化
    void demo() const { cout << m_i * m_i << endl; }
    void error() { m_i = 0; } // 編譯錯誤:不能修改 const 成員
};

關鍵點: 非靜態 const 成員**只能**在構造函數的初始化列表中初始化,不能在類內賦值,也不能在構造函數體內賦值。

3. 類的靜態 const 成員:全類共享的常量


class Test {
private:
    static const int m_i = 100; // 類內初始化(僅限整型/枚舉型)
public:
    void demo() const { cout << m_i << endl; }
};

注意: C++11 前,非整型靜態 const 成員需在類外定義;C++11 起支持類內初始化更多類型。靜態 const 成員屬於類,不佔用對象內存。

4. const 與指針:四種組合的語義差異

核心口訣:「看 const 在 * 的哪一邊」

聲明含義可修改指針值可修改指向值
const int* p / int const* p指向常量的指針是否
int* const p常量指針(指針本身不可變)否是
const int* const p指向常量的常量指針否否

代碼演示


int a = 123, b = 789;

// 1. 指向常量的指針
const int* p1 = &a; // *p1 = 456; // 錯誤
p1 = &b; // 合法

// 2. 常量指針
int* const p2 = &a; // p2 = &b; // 錯誤
*p2 = 456; // 合法,a 變為 456

// 3. 兩者結合
const int* const p3 = &a; // *p3 = 456; 錯誤;p3 = &b; 錯誤

5. const 與引用:避免拷貝且保護數據

引用本質是別名,天然適合配合 const 使用:


int a = 123;
const int& ref = a; // 只讀引用
// ref = 456; // 錯誤:不能通過 ref 修改
a = 456; // 合法:通過原變量可修改
cout << ref; // 輸出 456

為什麼函數參數常用 const T&?

  • 避免大對象拷貝開銷(傳值會調用拷貝構造函數)
  • 防止函數內部意外修改實參
  • 接受臨時對象/字面值(非常量引用不能綁定臨時對象)

void print(const string& s) { // 高效且安全
    cout << s << endl;
}

6. const 與函數:參數、返回值、成員函數

const 參數:防止修改實參


void f(const int& i) { // 保證不修改 i
    // i = 12; // 編譯錯誤
    cout << i * i << endl;
}

const 返回值:防止「函數調用作左值」


int& f(int& i) { i = 12; return i; } // 返回引用
f(a) = 33; // 合法但危險:f(a) 作為左值修改了 a

const int& f(int& i) { i = 12; return i; } // 返回 const 引用
f(a) = 33; // 編譯錯誤:禁止修改返回值

最佳實踐: 若返回引用/指針且不希望調用者修改,返回類型應加 const。

7. const 對象與 const 成員函數:const 正確性

const 對象只能調用 const 成員函數


class Test {
private:
    int m_i;
public:
    Test(int ii) : m_i(ii) {}
    void setVal(int i) { m_i = i; } // 非 const 成員函數
    void echoVal() const { cout << m_i << endl; } // const 成員函數
};

const Test obj(123);
obj.echoVal(); // 合法
// obj.setVal(456); // 編譯錯誤:const 對象不能調用非 const 成員函數

const 成員函數的承諾

在成員函數後加 const,承諾:

  • 不修改任何非靜態成員變量
  • 不調用任何非 const 成員函數

編譯器會強制檢查此承諾。mutable 關鍵字可豁免特定成員(如緩存、鎖)。

構造/析構函數與 const

  • 構造函數**不能**是 const(需初始化成員)
  • 析構函數**不能**是 const(需清理資源)
  • 但 const 對象的構造/析構正常調用

總結:const 最佳實踐清單

  1. 默認讓變量、參數、返回值、成員函數盡可能加 const
  2. 傳遞大對象參數用 const T&
  3. 返回引用/指針且不想被修改時加 const
  4. 不修改對象狀態的成員函數標記 const
  5. 用 const 替代 #define 定義常量

掌握 const,是寫出健壯、高效、可維護 C++ 代碼的關鍵一步。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved