☰
C++ const 相关的面试八股
2026/9/26 2:26:21 网站建设 项目流程

1const的本质与承诺

const关键字的核心是做出一个“承诺”:承诺其所修饰的对象(变量、指针、引用、成员函数等)的“不变性”。它告诉编译器和代码的阅读者:“这个值/这个对象的状态,在这里不会被改变。”
编译器会强制检查这个承诺,违反则报错。这增强了代码的安全性、可读性和可维护性。


2const的常见用法“八股”

2.1常量变量

  • 作用:定义一个编译期或运行期的常量,值初始化后不可修改。
  • 与#define宏的区别:
    • const常量有类型检查,更安全。
    • const常量在编译、链接时遵循作用域规则,而宏是简单的文本替换,无作用域。
    • const常量从汇编角度看,通常会被编译器优化。
constintMAX_SIZE=100;// 编译期常量(通常)constintvalue=getValue();// 运行期常量// MAX_SIZE = 200; // 错误:不可修改

2.2const与指针

这是经典的面试考点,关键看const修饰的是谁。

  • 常量指针(指针是常量)

    inta=10,b=20;int*constp=&a;// p 本身是常量,指向不能变// p = &b; // 错误:p 的指向不可修改*p=30;// 正确:p 指向的值(a)可以被修改

    口诀:const在*右边,指针本身不可变。

  • 指向常量的指针(指向的数据是常量)

    inta=10,b=20;constint*p=&a;// 等价于 int const* p// *p = 30; // 错误:不能通过 p 修改 ap=&b;// 正确:p 的指向可以改变

    口诀:const在*左边,指向的数据不可变(通过该指针)。

  • 指向常量的常量指针(两者都不可变)

    inta=10;constint*constp=&a;// p = &xxx; // 错误// *p = 20; // 错误

2.3const与引用

  • 常量引用:不能通过该引用修改所绑定的对象。这是最常用的const引用形式,常用于函数参数,避免拷贝,同时保证不修改实参。
    intx=5;constint&ref=x;// ref 是 x 的常量引用// ref = 10; // 错误x=10;// 正确,但 ref 看到的值也变成了 10
  • 关键特性:常量引用可以绑定到右值(临时对象、字面量),这是普通引用做不到的。
    constint&r=42;// 合法// int& r = 42; // 非法voidfunc(conststd::string&str);// 可以接收字符串字面量:func(“hello”)

2.4const成员函数

这是类设计的核心,用于表明该成员函数不会修改对象的成员变量(除非成员被mutable修饰)。

  • 语法:在成员函数声明的参数列表后加上const。
  • 作用:
    1. 安全:编译器保证函数内不会修改非mutable的成员。
    2. 设计意图:告诉使用者这是一个“只读”操作。
    3. 关键作用:const对象只能调用const成员函数。这使得程序能正确地对常量对象进行操作。
classMyClass{public:intgetValue()const{// const 成员函数// value_ = 10; // 错误!不能修改成员变量returnvalue_;}voidsetValue(intv){// 非 const 成员函数value_=v;}private:intvalue_;mutableintcache_;// mutable 成员即使在 const 函数中也可被修改};constMyClass obj;intx=obj.getValue();// 正确:const 对象调用 const 函数// obj.setValue(5); // 错误:const 对象不能调用非 const 函数
  • 重载依据:const可以作为成员函数重载的依据。编译器根据调用对象的const性来选择版本。
    classText{char&operatorstd::size_t pos{returntext[pos];}// 用于普通对象constchar&operatorstd::size_t posconst{returntext[pos];}// 用于 const 对象};

2.5const与函数参数和返回值

  • 参数:使用const引用(const T&)传递不希望被修改的大型对象,效率高且安全。使用const指针(const T*)同理。
  • 返回值:
    • 返回const值(如const T):对于内置类型意义不大,对于类对象可以防止返回值被用作左值(如(a*b) = c;这种无意义的操作),但在 C++11 后的移动语义下较少用。
    • 返回const引用/指针:常见于返回成员变量的引用/指针,并希望调用者不能通过它修改对象内部状态。但要警惕返回指向局部对象的引用/指针!

2.6顶层const与底层const

这是 C++ 标准中的精确概念,有助于理解复杂的类型声明。

  • 顶层const:表示对象本身是常量。适用于任意数据类型。
    inta=0;int*constp1=&a;// p1 本身是 const(顶层)constintb=0;// b 本身是 const(顶层)
  • 底层const:表示指针或引用所指向的对象是常量。
    constint*p2=&a;// p2 指向的对象是 const(底层)constint&r=a;// r 指向的对象是 const(底层)constint*constp3=&a;// 左边底层 const,右边顶层 const
  • 在拷贝时的区别:
    • 顶层const不影响拷贝,因为拷出和拷入的对象是独立的。
    • 进行拷贝时,拷入和拷出的对象必须具有相同的底层const资格,或者能从非const转换为const(反之则不行)。
    constintc=10;intd=c;// 正确:顶层 const 被忽略constint*p4=&a;// 底层 constint*p5=p4;// 错误:p4 有底层 const,p5 没有constint*p6=p4;// 正确:两者都有相同的底层 const

3 进阶与相关考点

  1. mutable关键字:用于修饰类的成员变量,表示它在const成员函数中也可以被修改(常用于缓存、互斥锁等场景)。
  2. const_cast运算符:用于移除对象的const或volatile属性。极其危险,除非你确切知道被转换的原始对象本身不是常量(例如,向接收非const指针的旧式 C 接口传递数据时)。
  3. constexpr(C++11):比const更强大,用于定义编译期常量,并要求常量表达式能在编译时求值。可用于变量、函数、构造函数等。constexpr函数如果传入编译期常量,则结果也是编译期常量。
  4. 与volatile的区别:const告诉编译器“不要变”,volatile告诉编译器“可能会意外改变”(防止优化,常用于硬件映射内存)。

4 面试回答思路

回答时可以按层次展开:

  1. 定性:const是承诺不变性,由编译器保证。
  2. 分场景:从变量 -> 指针/引用 -> 函数参数 -> 成员函数 -> 返回值,逐一说明。
  3. 点出关键:
    • 指针的const在*左/右的区别。
    • 常量引用的绑定特性。
    • const成员函数的双重意义(不修改对象、使const对象可调用)。
    • 顶层/底层const的概念。
  4. 提及周边:简单提一下mutable、const_cast和constexpr的作用与注意事项。

掌握这些,就掌握了 C++const的绝大部分“八股”内容。理解其背后的“承诺与保证”思想,比死记硬背语法更重要。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询