const 该放哪:从顶层 const 到 const 成员函数
2026/9/24 17:44:48 网站建设 项目流程

const在 C++ 里不是「加个修饰」那么简单——放在*左边还是右边,含义完全不同;放在成员函数末尾,改的甚至是隐藏的this指针类型。搞混这两者,轻则编译报错,重则写出自以为只读、其实能改的接口。这篇把const的位置语义、它对函数签名和性能的影响,用代码和真实输出讲清楚。

官方文档:cv 限定符(const/volatile)、成员函数

1. 引子:const int* 和 int* const 到底谁不能改

一句话区分:const紧贴谁,谁就不能改

  • const int* pconst*左边,修饰「指向的对象」——*p不能改,p能改(可指向别处)。
  • int* const pconst*右边,修饰「指针本身」——p不能改,*p能改。
  • const int* const p:两边都有,p*p都不能改。

2. 三种写法,逐个类型实证

std::is_same把三种指针的精确类型钉出来:

// demo.cpp — 编译: g++ -std=c++17 -Wall -O2 demo.cpp -o demo#include<iostream>#include<type_traits>intmain(){intn=1;constintc=2;constint*p1=&c;// 指向 const int 的指针(底层 const)int*constp2=&n;// const 指针(顶层 const)constint*constp3=&c;// 顶层 + 底层 conststatic_assert(std::is_same<decltype(p1),constint*>::value,"");static_assert(std::is_same<decltype(p2),int*const>::value,"");static_assert(std::is_same<decltype(p3),constint*const>::value,"");std::cout<<"p1: const int* = "<<std::is_same<decltype(p1),constint*>::value<<'\n';std::cout<<"p2: int* const = "<<std::is_same<decltype(p2),int*const>::value<<'\n';std::cout<<"p3: const int* const = "<<std::is_same<decltype(p3),constint*const>::value<<'\n';}
p1: const int* = 1 p2: int* const = 1 p3: const int* const = 1

用一张图记住位置:

const int* p1; 底层 const:指针可变,所指不可变 ↑修饰所指对象 p1 = &x; ✓ *p1 = 0; ✗ int* const p2; 顶层 const:指针不可变,所指可变 ↑修饰指针本身 p2 = &x; ✗ *p2 = 0; ✓ const int* const p3; 两层都 const ↑所指 ↑指针

3. 顶层 const(top-level)与底层 const(low-level)

这两个词是理解「为什么 const 影响重载、又不影响另一些重载」的关键:

  • 顶层 const:修饰「对象自己」(int* constconst int x)。
  • 底层 const:修饰「指针/引用指向的东西」(const int*const int&)。

关键规则:函数按值传参时,顶层 const 会被忽略,不构成重载;底层 const 不会忽略,构成重载。

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

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

立即咨询