C++中的const
C++中的const
顶层const和底层const
定义
顶层const代表指针本身是一个常量,而底层const则表示指针指向的对象是一个常量。
int a = 10;
const int *p = &a; // 底层const, 不能通过*p改变a,又叫指向常量的指针。
int* const p = &a; // 顶层const, p本身的值不能发生改变,又叫常量指针。
const int* const p = &a; // 顶层const + 底层const
拷贝操作
当进行拷贝操作时,顶层const不起作用(拷贝不会改变对象本身的值),但拷入和拷出对象的底层const应该一样,或者可以转化为相同的const类型(非const可以转化为const)。
const int a = 10;
const int b = a; // 正确,顶层const不起作用
int c = a; // 正确,顶层const不起作用
const int *p1 = &a; // 正确,底层非const可以转化为底层const
int *p2 = p1; // 错误,p1的底层const不能转化为底层非const
int* const p3 = p1; // 错误,p1的底层const不能转化为底层非const
constexpr
constexpr总是把对象声明为顶层const
constexpr int *p1 = nullptr; // 相当于 int* const p1 = nullptr;
constexpr const int *p2 = nullptr; // 相当于 const int* const p2 = nullptr;
typedef
在typedef复合类型的时候,不能简单地把typedef展开。下面的例子说明了这一情况。
typedef char *pstring;
const pstring cstr = 0;
const pstring *ps;
在这里,cstr是指向char的常量指针,而ps是一个指针,它指向的对象是一个指向char的常量指针。原因如下:这两条声明语句的基本数据类型都是 const pstring ,const是对给定类型的修饰,而给定的类型是 pstring ,也即 char * ,所以const修饰的是指向char的指针,也即,这个指针是一个常量,因此 const pstring 声明的类型是 char * const 类型。
这与直接把typedef展开时的理解是完全不同的。直接展开时,const pstring就变成了const char * ,前者的数据类型是指针,而后者的数据类型是char, * 只是声明符的一部分。如果直接展开的话,上述语句就变成了
const char *cstr = 0;
const char **ps;
这样一来,cstr就变成了一个指向char类型常量的指针,ps变成了一个指向const char * 类型的指针。
auto
auto一般会忽略掉顶层const和引用,保留底层const。
const int ci = 1, &cr = ci;
auto b = ci; // int
auto c = cr; // int
auto d = &ci; // const int *,因为对顶层const对象取地址得到底层const
当需要auto带顶层const时,应explicly写出。
const auto &r = 1;
decltype
decltype将会保留变量的顶层const和引用。
const int ci = 0, &cr = ci;
decltype(ci) x = 0; // const int
decltype(cr) y = 0; // const int &
decltype(cr) z; // 错误,类型为const int &,必须绑定到一个对象上
若decltype接受一个变量,则推断出变量的类型;若接受一个表达式,则分两种情况:
-
表达式是一个左值,则得到对应类型的引用。(因为可以使用左值得到对应的对象,且能对对象进行赋值,这与引用的功能相同)
-
表达式是一个右值,则得到对应的类型。
若在变量的两边加上一对或多对括号,则变量会被当成是一个表达式,且这个表达式是一个左值,所以一定将得到对应类型的引用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现