当前位置: 首页 > article >正文

Effective C++读书笔记——item3(疯狂使用const)

1. const 的基本作用与特性

  • 语义约束:const 能指定对象不应被修改这一语义约束,编译器会执行该约束,可借助它减少因意外修改值而产生的错误,同时向编译器和其他程序员表明某个值应保持不变。
  • 应用范围广泛:在类的外部,可用于全局、命名空间范围的常量,以及文件、函数、模块范围内声明为静态的对象;在类内部,可用于静态和非静态数据成员;对于指针,能指定指针本身、所指数据或者两者是否为常量等多种情况。
  • 语法规则:const 出现在星号左边,表示指针指向的内容为常量;出现在星号右边,表示指针自身为常量;出现在两边,则两者都是常量。对于函数参数中 const 放在类型之前或之后星号之前,意义无区别。

2. const 在不同场景中的应用及影响

  • 迭代器方面:声明迭代器为 const 类似于声明指针为 const,即不能改变迭代器的指向,但指向的内容可变化;若要迭代器指向不能变化的内容,需使用 const_iterator。
  • 函数声明方面
    • 返回值为 const:函数返回常量值可减少客户错误造成的影响,如将自定义类型的操作符重载函数(如 operator*)的返回值声明为 const,能避免对运算结果进行不合理赋值的情况。
    • 参数为 const:其行为类似局部的 const 对象,在不需要改变参数或本地对象时,应将其声明为 const,有助于避免因误操作(如将 “==” 写成 “=”)带来的错误。
    • const 成员函数:被声明为 const 的成员函数可被 const 对象调用,这使类的接口更易理解,且利于以传引用给 const 的方式传递对象来提升程序性能;成员函数可基于常量性不同进行重载,不同版本的重载函数能针对 const 和非 const 对象进行不同操作。

3. const 相关的两种常量性概念

  • 二进制位常量性(bitwise constness):认为成员函数只要不改变对象的非静态数据成员(即对象内的二进制位)就是 const,编译器易监测其违例,但存在局限性,如某些改变指针指向内容的函数虽能通过该检验,但实际效果并非真正的 const。
  • 逻辑常量性(logical constness):主张 const 成员函数可在客户无法察觉的情况下改变对象中的一些二进制位,但编译器默认遵循二进制位常量性,对于逻辑常量性相关情况不认可。可利用 mutable 关键字将非静态数据成员从二进制位常量性约束中解放出来,使其能在 const 成员函数中被修改。

4. 避免 const 与非 const 成员函数重复代码的方法

  • 利用强制转型:当 const 和非 const 成员函数实现基本相同时,为避免代码重复,可让非 const 版本调用 const 版本,通过适当的强制转型(如先使用 static_cast 为 this 指针加上 const 以调用 const 版本的函数,再用 const_cast 去掉 const 版本函数返回值的 const 属性)来实现,不过一般情况下应避免强制转型,仅在此种特殊场景下为避免重复代码可采用;反向地从 const 成员函数调用非 const 成员函数是错误的,因为可能改变本应保持不变的对象状态。

5. 总结要点

  • 将相关内容声明为 const 有助于编译器发现使用错误,其能应用于多种范围的对象、函数参数、返回类型以及成员函数等方面。
  • 编程时应从概念上的常量性(conceptual constness,即 logical constness)角度考虑,尽管编译器坚持二进制位常量性。
  • 当 const 和非 const 成员函数有相似实现时,使用非 const 版本调用 const 版本可避免代码重复。

http://www.kler.cn/a/467291.html

相关文章:

  • 力扣23.合并K个升序链表
  • AngularJS HTML DOM
  • Vue3实现PDF在线预览功能
  • 51单片机——LED模块
  • Tableau数据可视化与仪表盘搭建-安装教程
  • HTML——66.单选框
  • Kafka 生产者
  • 关于嵌入式系统的知识课堂(二)
  • Jenkins(持续集成与自动化部署)
  • 2453.学习周刊-2024年53周
  • #渗透测试#漏洞挖掘#WAF分类及绕过思路
  • Istio 补充 Kubernetes 的不足
  • Jetpack Compose 学习笔记(四)—— CompositionLocal 与主题
  • h5页面在安卓手机被软键盘弹起引起的bug
  • Python 实时获取Linux服务器信息
  • C++Primer 变量
  • 选择IT驻场外包公司,要找有哪些资质的公司
  • 【JAVA】switch ... case ... 的用法
  • OSI模型的网络层中产生拥塞的主要原因?
  • MTR 网络诊断工具实战详解
  • 深度解析如何在Linux中创建自己的第一个系统程序---进度条
  • FastAPI 响应模型与自定义响应
  • 树莓派linux内核源码编译
  • 第四届电子信息与通信工程国际学术会议(EICE 2025)
  • ASCII 码表
  • 【翻译】审慎对齐:推理使更安全的语言模型成为可能