商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > C++中const修饰符用法 _ 常量指针与指针常量的区别【详解】

C++中const修饰符用法 _ 常量指针与指针常量的区别【详解】

  发布于2026-07-18 阅读(0)

扫一扫,手机访问

在C++里,const修饰指针时,位置不同,语义截然不同。这可不是什么“差不多”的事,编译器会据此进行完全不同的类型检查。位置写错,轻则函数调用失败,重则逻辑被绕过却毫无报错。

const int* p 和 int* const p:编译期就不是同一个类型

前者是“指向常量的指针”,后者是“常量指针”。它们在类型系统里互不兼容,不能隐式转换,也不能用于重载区分(因为顶层cv-qualifier不参与函数签名)。

  • const int* p:可以改变p的值(即换地址),但不能改变*p(即不能写*p = 5)。
  • int* const p = &x:必须初始化;之后p = &y会报错,但*p = 5是合法的。
  • const int* const p = &x:两者都禁止,是最严格的只读访问。
  • 一个实用的读法是从右往左:int* const p → “p is a const pointer to int”。

字符串字面量:强制要求const char*

"hello"这种字面量,类型是const char[6]。现代C++(C++11起)禁止隐式转成char*。这不是警告,是硬性编译错误。

  • 错误写法:char* p = "hello"; → error: cannot convert 'const char*' to 'char*'
  • 正确写法:const char* p = "hello";
  • 如果非要非常量指针(极少见且危险):char* p = const_cast("hello");,但后续写操作仍是未定义行为(UB)。
  • 安全替代方案:char p[] = "hello";(数组初始化,不涉及const转换)。

const成员函数:内部只能调用const成员函数

声明为void foo() const的函数,其this指针类型是const MyClass*。这意味着所有非mutable成员变量都变成只读,且只能调用其他const成员函数。

  • 常见报错:error: passing 'const MyClass' as 'this' argument discards qualifiers
  • 典型场景:const std::vector& v 只能调用v.size()v.at(i),不能调用v.push_back(x)
  • mutable是唯一例外:它允许在const函数中修改(比如缓存计算结果),但该字段不能影响对象的逻辑状态。
  • 返回*this时,如果写成const MyClass&,链式调用后续将无法接非const函数。

const引用参数:不只是“防手抖”,更是契约与生命周期管理

void f(const std::string& s),重点不在于防止你内部误改s,而在于告诉调用方:“我不会动你传来的对象”,并让编译器据此优化(如省去隐式拷贝)和延长临时对象生命周期。

  • 接受临时对象:f(std::string("tmp"))合法;而void f(std::string& s)不合法。
  • 注意:const T&延长的是绑定到它的那个临时对象的生命周期,不传递给函数内部创建的新引用。
  • 一个更隐蔽的坑:如果T自身没实现const正确性(比如成员函数没加const),哪怕参数是const T&,调用其非const成员也会失败。
  • 基本类型(intdouble)传const int&没实际收益,编译器通常忽略;大对象才值得这么做。

真正难的不是记住哪边是“指针常量”,而是写出const正确的类——每个访问器是否标记const,哪些字段该加mutable,返回引用时要不要const,这些组合起来才构成完整的只读契约。漏掉一个点,整个const系统就形同虚设。

本文转载于:https://www.php.cn/faq/2345751.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注