C++中const修饰符怎么用_C++常量指针与指针常量的区别【难点】

5次阅读

constc++中定义真正不可修改的常量,其位置决定修饰对象:const修饰左侧最近成分,指针场景下int const与const int语义截然不同。

C++中const修饰符怎么用_C++常量指针与指针常量的区别【难点】

const 修饰符在 C++ 中不是“只读变量”,而是定义真正不可修改的常量(编译期或运行期确定),用错位置会导致语义完全相反——尤其是指针场景,const int* pint* const p 根本不是一回事。

const 放在 * 左边还是右边?看它紧挨着谁

核心规则:const 修饰它**左边最近的类型成分**;如果左边没东西,就修饰右边的。这是理解所有组合的基础。

  • const int* p 等价于 int const* p:const 修饰 int → 指针所指的 int 不可改,但指针本身可指向别处
  • int* const p = &x:const 修饰 *(即指针本身)→ p 的地址不可改,但 *p 可以赋新值
  • const int* const p = &x:两个 const 各管各的 → 指针不能换、所指内容也不能改

为什么 char* p = "hello" 在现代 C++ 中会报错?

字符串字面量(如 "hello")类型是 const char[6],隐式转成 const char*。旧代码允许转成 char* 是历史遗留,C++11 起禁止,否则可能误写导致未定义行为。

  • 正确写法:const char* p = "hello"(推荐)或 auto p = "hello"(自动推导为 const char*)
  • 若真需要可修改副本:char p[] = "hello"(数组初始化,不涉及 const 转换)
  • 强行绕过(不推荐):char* p = const_cast("hello") → 写操作仍 UB

函数参数里 const 引用和 const 指针的实际意义

它们不只是“防手抖”,关键在于影响重载决议、模板推导和对象生命周期管理。

立即学习C++免费学习笔记(深入)”;

  • void f(const std::String& s):避免拷贝,且接受临时对象(如 f(std::string("tmp"))
  • void f(std::string& s):不能传临时对象,也不能传 const 对象
  • void g(const int* p):可接收 int*const int*,但无法通过 p 修改原值
  • 注意:const 在参数声明中是顶层 cv-qualifier,不影响函数签名唯一性(void f(int*)void f(const int*) 不能重载)

const 成员函数:不只是“不改成员变量

void foo() const 表示该函数承诺不修改 this 对象的**任何非 mutable 成员**,但它能调用其他 const 成员函数、能读取所有成员、也能返回内部 const 引用——更重要的是,它决定了能否被 const 对象调用。

  • 非常量对象可以调用 const 和非 const 版本;const 对象只能调用 const 版本
  • mutable 成员可在 const 函数中修改(常用于缓存、计数器等不影响逻辑状态的字段)
  • 返回 *this 的 const 成员函数,返回类型是 const X&,链式调用时后续操作受限制(比如不能接非 const 函数)

最易忽略的一点:const 正确性不是编译器“提醒你”,而是类型系统强制约束。一旦接口把某个参数声明为 const T*,调用方传入的指针是否带 const 就参与了类型匹配;而成员函数的 const 限定直接决定对象能否调用它——这不是风格问题,是契约的一部分。

text=ZqhQzanResources