最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ 的 const 相關(guān)知識(shí)點(diǎn)總結(jié)

 更新時(shí)間:2026年05月18日 10:58:40   作者:basketball616  
這篇文章詳細(xì)介紹了C++中的const關(guān)鍵字,包括基礎(chǔ)概念、指針和const的關(guān)系、頂層const與底層const的區(qū)別、const在函數(shù)和成員函數(shù)中的應(yīng)用、mutable的關(guān)鍵字作用,感興趣的朋友跟隨小編一起看看吧

const 大概是 C++ 初學(xué)者最早接觸的關(guān)鍵字之一,但它絕不僅僅表示“一個(gè)不可修改的常量”。隨著學(xué)習(xí)的深入,你會(huì)發(fā)現(xiàn)它在類型安全、編譯器優(yōu)化、接口設(shè)計(jì)乃至多線程編程中都扮演著重要角色。

1. 基礎(chǔ)篇:定義一個(gè)常量

最簡(jiǎn)單的用法,讓變量值不可修改。

const int MAX_SIZE = 100;
// MAX_SIZE = 200; // 錯(cuò)誤!不能修改
int const MAX_SIZE_2 = 100; // 與上一行完全等價(jià),const 在類型前后均可

要點(diǎn)

  • const 修飾的變量必須初始化,否則之后也沒機(jī)會(huì)賦值了。
  • const intint const 是一樣的,但為了風(fēng)格統(tǒng)一,通常把 const 寫在最前面。

const 與宏常量的區(qū)別

在 C++ 中,更推薦使用 constconstexpr 代替 #define 定義常量,因?yàn)樗蓄愋蜋z查,且遵循作用域規(guī)則。

2. 指針與 const:厘清誰(shuí)是不可變的

這是最繞也是面試最愛考的地方。記住核心:看 const 在 * 的哪一邊

2.1 指向常量的指針

int value = 10;
const int* ptr = &value; // 等同于 int const* ptr
  • 含義:不能通過 ptr 修改其所指對(duì)象的值 (*ptr = 20 是錯(cuò)的)。
  • ptr 自身可以指向別的對(duì)象,而且 value 本身如果不是 const,仍可通過 value 直接修改。

2.2 常量指針

int value = 10;
int* const ptr = &value;
  • 含義ptr 本身的值(即指向的地址)不可變,一旦初始化就不能再指向別處。
  • :可以通過 *ptr 修改所指對(duì)象的值。

2.3 指向常量的常量指針

const int value = 10;
const int* const ptr = &value;
  • 含義:指針本身不可變,且不能通過它修改所指對(duì)象。一切都被鎖定。

記憶技巧:以 * 為界,const 在左修飾指向的對(duì)象,在右修飾指針本身。所以 const int * 修飾的是 int,int * const 修飾的是指針。

3. 頂層 const 與底層 const

這個(gè)概念在泛型編程和類型推導(dǎo)中尤為重要。

  • 頂層 const:表示指針本身對(duì)象本身是常量。
    int i = 0;
    int *const p1 = &i;  // 頂層 const,p1 不可變,一旦初始化就不能再指向別處。
    const int ci = 42;   // 頂層 const,ci 不可變
    
  • 底層 const:表示所指對(duì)象所引用對(duì)象是常量。
    const int *p2 = &ci;  // 底層 const,*p2 不可變
    const int &r = ci;    // 底層 const,r 引用的對(duì)象不可變
    

關(guān)鍵區(qū)別

  • 拷貝頂層 const 不受影響,因?yàn)榭截悤r(shí)會(huì)復(fù)制值,原對(duì)象是否 const 無(wú)所謂。
    int a = ci; // 正確,ci 的頂層 const 被忽略
    
  • 底層 const 在拷貝時(shí)必須保持“常量”性質(zhì),不能將底層 const 的指針或引用賦給非 const 的指針或引用。
    const int *cp = &ci;
    int *p = cp; // 錯(cuò)誤!cp 是底層 const,不能給普通 int*
    

4. const 與函數(shù)

const 在函數(shù)中的應(yīng)用,是寫出健壯接口的關(guān)鍵。

4.1 const 形參

像普通變量一樣,函數(shù)內(nèi)部不會(huì)修改形參時(shí),可以用 const 修飾。但注意,在函數(shù)聲明中,頂層 const 會(huì)被忽略:

void func(int val);          // 1
void func(const int val);    // 2 與 1 重復(fù)聲明!頂層 const 被忽略

而對(duì)于指針和引用,底層 const 則有實(shí)質(zhì)區(qū)別:

void func(int& val);         // 只能接受普通左值
void func(const int& val);   // 可以接受 const 或非 const 的左值/右值

使用 const & 作為參數(shù)是避免拷貝、同時(shí)保護(hù)原數(shù)據(jù)的最佳實(shí)踐。

4.2 const 返回類型

返回一個(gè) const 值類型通常沒有意義(如 const int func()),因?yàn)檎{(diào)用者拷貝后本來就可以隨便改。但它常用于返回指針或引用,防止調(diào)用者通過返回值修改內(nèi)部數(shù)據(jù)。

class MyClass {
    int data;
public:
    const int& getData() const { return data; } // 返回底層 const 引用
};

5. const 成員函數(shù):接口設(shè)計(jì)的精髓

這是面向?qū)ο笾械闹仡^戲。

語(yǔ)法:在成員函數(shù)參數(shù)列表后加 const 關(guān)鍵字。

class Widget {
private:
    int value;
public:
    int getValue() const {  // 常量成員函數(shù)
        // value = 10;      // 錯(cuò)誤!不能修改任何非 mutable 成員變量
        return value;
    }
};

作用

  1. 承諾不修改對(duì)象狀態(tài):在函數(shù)體內(nèi),this 指針的類型是 const Widget* const,因此不能修改非 mutable 成員。
  2. 可被 const 對(duì)象調(diào)用const Widget w; w.getValue(); 是合法的。普通對(duì)象也可以調(diào)。
  3. 構(gòu)成重載:可以根據(jù)成員函數(shù)是否為 const 來重載。
class Widget {
public:
    void display() { std::cout << "non-const\n"; }
    void display() const { std::cout << "const\n"; }
};
Widget w;
w.display();       // 調(diào)用普通版本
const Widget cw;
cw.display();      // 調(diào)用 const 版本

mutable 的妙用

如果一個(gè) const 成員函數(shù)確實(shí)需要修改某個(gè)與對(duì)象邏輯狀態(tài)無(wú)關(guān)的變量(如緩存、互斥鎖),可將該變量聲明為 mutable。

class Cache {
    mutable int cachedValue;
    mutable std::mutex mtx;
public:
    int getValue() const {
        std::lock_guard<std::mutex> lock(mtx); // 可以在 const 函數(shù)內(nèi)加鎖
        if (cachedValue < 0) cachedValue = compute();
        return cachedValue;
    }
};

6. const 與迭代器

STL 迭代器與指針類似,也有 const 之分。

std::vector<int> vec = {1, 2, 3};
const std::vector<int>::iterator iter = vec.begin(); // 迭代器本身是 const
*iter = 10; // 可以修改所指元素
// ++iter;  // 錯(cuò)誤,迭代器本身不可變
std::vector<int>::const_iterator cIter = vec.begin(); // 所指元素是 const
// *cIter = 10; // 錯(cuò)誤,不能修改元素
++cIter;       // 可以,迭代器自身可變

需要元素不可變的遍歷時(shí),優(yōu)先使用 cbegin()cend()

總結(jié)

const 是 C++ 類型系統(tǒng)中的一位“守夜人”:

  • 對(duì)變量:聲明常量,強(qiáng)制初始化。
  • 對(duì)指針:通過相對(duì)位置區(qū)分不可變的是指針自身還是所指對(duì)象。
  • 對(duì)函數(shù)const & 傳參防止拷貝和修改;const 返回值保護(hù)內(nèi)部數(shù)據(jù)。
  • 對(duì)類const 成員函數(shù)是可被常量對(duì)象調(diào)用的安全接口,mutable 處理物理常量性與邏輯常量性的分離。

掌握 const 不僅僅是記住語(yǔ)法,更重要的是形成“用 const 告訴編譯器你的不變性約束”的思維習(xí)慣,這樣才能寫出更安全、更清晰的 C++ 代碼。

希望這篇梳理對(duì)你有幫助,const 的世界很清晰,多寫多練就不容易暈了。

一、基礎(chǔ)概念題

1. const 變量必須在定義時(shí)初始化嗎?為什么?

答案要點(diǎn):必須初始化。因?yàn)?const 對(duì)象一旦創(chuàng)建,其值就不能再改變,若不初始化,它將永遠(yuǎn)擁有一個(gè)不確定的值。

2. const int 和 int const 有區(qū)別嗎?

答案要點(diǎn):沒有區(qū)別,完全等價(jià)。當(dāng) const 修飾的是基本類型且沒有指針參與時(shí),位置不影響含義。

3. const 與 #define 定義常量有什么區(qū)別?

答案要點(diǎn)

  • const 有類型檢查,#define 只是文本替換。
  • const 遵循作用域規(guī)則,#define 從定義處到文件結(jié)束(或 #undef)。
  • const 可以被調(diào)試器看到,#define 宏名在編譯預(yù)處理后就被替換了。
  • 在 C++ 中更推薦用 constconstexpr。

二、指針與 const(必考,高頻)

4. 解釋 const int *p 和 int *const p 的區(qū)別。

答案要點(diǎn)

  • const int *p:指向常量的指針,不能通過 *p 修改所指對(duì)象,但 p 可以指向別處。
  • int *const p:常量指針,p 本身不可變(不能指向別處),但可以通過 *p 修改所指對(duì)象。

5. 以下代碼錯(cuò)在哪?

int a = 10;
const int *p = &a;
int *q = p;   // 這行有什么問題?

答案要點(diǎn):錯(cuò)誤,p 是底層 const,q 是普通指針。如果把 p 賦給 q,就可以通過 *q 修改一個(gè) const int 指向的對(duì)象,破壞了常量性。需要改為 const int *q = p; 或強(qiáng)制類型轉(zhuǎn)換(不推薦)。

6. 判斷對(duì)錯(cuò)并解釋:

const int a = 10;
int *p = (int*)&a;
*p = 20;

答案要點(diǎn):代碼可能編譯通過,但行為是未定義的a 本身是 const 對(duì)象,可能被放在只讀內(nèi)存區(qū),強(qiáng)制修改會(huì)導(dǎo)致運(yùn)行時(shí)崩潰或奇怪的優(yōu)化行為。不要這樣做。

三、頂層 const 與底層 const

7. 什么是頂層 const?什么是底層 const?各自在賦值時(shí)有什么影響?

答案要點(diǎn)

  • 頂層 const:對(duì)象本身是常量(如 const int a 中的 a,或 int *const p 中的 p)。
  • 底層 const:所指/所引用的對(duì)象是常量(如 const int *p 中的 *p,或 const int &r 中的引用對(duì)象)。
  • 賦值時(shí),頂層 const 可以被忽略(拷貝出新值),底層 const 必須保持一致性,不能把底層 const 賦給非 const。

8. 給定代碼,判斷能否編譯:

int i = 0;
const int ci = i;
const int *p1 = &ci;
int *const p2 = &i;
p1 = p2;      // (1)
p2 = p1;      // (2)
const int *const p3 = p2;  // (3)

答案要點(diǎn)

  • (1) 可以,p2 是頂層 const,賦值給 p1(底層 const)沒問題,p1 的底層 const 保持不變。
  • (2) 不可以,p2 是頂層 const 指針,本身不能被賦值。
  • (3) 可以,p2 的底層是 non-const,賦給 const int 是安全的。

四、const 與函數(shù)

9. 這兩個(gè)函數(shù)聲明是否構(gòu)成重載?為什么?

void f(int);
void f(const int);

答案要點(diǎn):不構(gòu)成重載,這是重復(fù)聲明。頂層 const 在函數(shù)參數(shù)中被忽略,編譯時(shí)會(huì)報(bào)重復(fù)定義。因?yàn)樗鼈兘邮艿膶?shí)參類型沒有區(qū)別。

10. 以下函數(shù)各自能接受什么類型的實(shí)參?

void f1(int&);
void f2(const int&);

答案要點(diǎn)

  • f1 只能接受非 const 的左值,不能接受 const 對(duì)象或右值(字面量、臨時(shí)對(duì)象等)。
  • f2 可以接受任何 int 類型的實(shí)參:非 const 左值、const 左值、右值。const & 是一個(gè)通用的只讀引用。

11. 返回 const 引用有什么意義?和返回值類型有什么區(qū)別?

答案要點(diǎn)

  • 返回 const 引用可以避免拷貝,同時(shí)保護(hù)內(nèi)部數(shù)據(jù)不被調(diào)用者修改。
  • 如果返回值類型(非引用),調(diào)用者得到的是副本,返回值的 const 修飾沒有實(shí)際意義,調(diào)用者可以隨意修改副本。

五、const 成員函數(shù)(高頻)

12. 什么是 const 成員函數(shù)?它有什么作用?

答案要點(diǎn)

  • 在成員函數(shù)參數(shù)列表后加 const 修飾,承諾該函數(shù)不會(huì)修改對(duì)象的狀態(tài)。
  • 作用:
    • 可以被 const 對(duì)象調(diào)用。
    • 與普通成員函數(shù)構(gòu)成重載。
    • 明確代碼意圖,增加安全性。

13. 簡(jiǎn)述 mutable 關(guān)鍵字的作用,并給出一個(gè)典型使用場(chǎng)景。

答案要點(diǎn)

  • mutable 修飾的成員變量,即使在 const 成員函數(shù)中也可以被修改。
  • 典型場(chǎng)景:緩存數(shù)據(jù)、互斥鎖(在 const 函數(shù)中加鎖以保護(hù)線程安全)、訪問計(jì)數(shù)器等。這些變量的改變不影響對(duì)象的“邏輯常量性”。

14. 分析以下代碼的輸出:

class A {
public:
    void show() { cout << "non-const" << endl; }
    void show() const { cout << "const" << endl; }
};
int main() {
    A a;
    const A ca;
    a.show();
    ca.show();
    return 0;
}

答案要點(diǎn):輸出 non-constconst。const 對(duì)象調(diào)用 const 版本,非 const 對(duì)象優(yōu)先調(diào)用非 const 版本。

15. const 成員函數(shù)中,this 指針的類型是什么?

答案要點(diǎn)const 類名* const。即指向常量對(duì)象的常量指針,因此不能通過 this 修改成員變量(mutable 除外)。

六、const 與迭代器

16. iterator 和 const_iterator 有什么區(qū)別?

答案要點(diǎn)

  • iterator:可讀寫所指元素。
  • const_iterator:只能讀,不能修改元素(*it 返回 const 引用)。類似于 const T*
  • 還有 const iterator(迭代器本身是常量),類似于 T* const,實(shí)際使用較少。

17. cbegin() / cend() 的作用是什么?

答案要點(diǎn):無(wú)論容器本身是否為 const,都返回 const_iterator,便于編寫只讀遍歷代碼,增強(qiáng)安全性。

這些題目覆蓋了 const 在面試中從基礎(chǔ)到進(jìn)階的核心考察點(diǎn),如果能全部清晰回答,const 這塊基本就算過關(guān)了。

到此這篇關(guān)于C++ 的 const 相關(guān)知識(shí)點(diǎn)總結(jié)的文章就介紹到這了,更多相關(guān)C++ const內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

图们市| 乳源| 闽清县| 杨浦区| 如皋市| 札达县| 固镇县| 化州市| 延安市| 武强县| 六安市| 石门县| 昆明市| 凤庆县| 柯坪县| 平山县| 桐庐县| 阿巴嘎旗| 十堰市| 文山县| 清流县| 开平市| 修武县| 海阳市| 阳谷县| 光泽县| 时尚| 阳高县| 昌平区| 顺义区| 平顶山市| 和龙市| 修文县| 杭锦后旗| 巴林左旗| 安远县| 宜宾市| 怀集县| 青龙| 商洛市| 阳新县|