一文搞懂顶层const和底层const

最近在准备秋招,复习到了const。看到了一些关于const的问题和回答。感觉大家在针对const的顶层和底层这个点上说的都不是很清楚。今天想借这个机会和大家一起聊聊顶层const和底层const到底是怎么一回事。

关于某个概念的理解,最正确的方法一定是看第一手资料(中/英文书籍 > 网络文章 >= 视频资料)。就像文章演的电视剧《雪豹》中有一幕:日本军官告诉周卫国,你是一个很好的将才,因为你懂外语,你能够获取的是第一手资料,不需要经过翻译的加工。举这个例子是想说明,通过视频或者文章了解某个知识点,吸收的是别人加工后的,不如自己从源头亲自了解。

1. 如何区分顶层const和底层const

首先,const有顶层和底层之分,起源是对指针的使用。指针作为一个对象,同时它还指向了另一个对象。因此,指针是不是一个常量,以及指针指向的对象是不是常量,这是两个问题。基于此,有了底层和顶层const的区分。

  • 用顶层const表明指针是一个常量
    • 指针不可变。不能对指针的指向进行修改。
  • 用底层const表明指针指向的对象是一个常量。
    • 指针指向的对象不可变。不能使用解引用运算符*对其进行修改。

后来,这个顶层和底层的概念从指针延展开来,对于任意数据类型,都可以使用这个概念。

2. 区分顶层和底层const的意义

正如我上面所说,指针是不是常量,和指针指向的对象是不是常量,这是两个问题,在实际使用上,不能混为一谈。

区分的意义主要有两点:

  • 第一: 执行对象拷贝时有限制,常量的底层const还是顶层const区别明显。
    这里我们还是用指针来进行说明:
int a = 10;
// 顶层const
int *const pTop = &a;
// 底层const
const int *pDeep = &a;

int *pNormal = pTop; // 正确。带有顶层const的指针能够赋值给普通指针
int *pNormal = pDeep;// 错误,const int * 不能转换为 int *

从这个demo中,顶层const的指针可以拷贝赋值给普通的指针,但是底层const的指针无法拷贝赋值给普通的指针。这便是两者在拷贝时的差别。

  • 第二:对于类型转换const_cast,只能去除底层const
int a = 10;
// 顶层const
int *const pTop = &a;
// 底层const
const int *pDeep = &a;
// 正确。const_cast去除了pDeep指针的底层const属性
int *pNormal = const_cast<int*>(pDeep); 
*pNormal = 20;
cout << a << endl; // 20

// const_cast无法去除顶层const
int b = 100;
const_cast<int*>(pTop) = &b; // 错误

3. 总结

其实顶层和底层const并不是一个复杂的概念。设计这个概念的目的是为了区分【指针是常量】和【指针指向的对象是常量】这两种情况。

对于顶层和底层的实际使用意义,记住底层const无法拷贝给没有const的对象就行了。(背const_cast的时候就知道了它只能去除底层const了)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值