[笔记]Effective C++ 条款3:尽可能使用const
2021/9/7 12:06:16
本文主要是介绍[笔记]Effective C++ 条款3:尽可能使用const,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
T* const 表示不可指向不同的东西 但指向的东西的值可以改变
const T* 表示不可改变指向的东西的值 但可以指向不同的东西
T* const p (const修饰p p为指针 被const修饰后不该被改动 指针p不能改变 但指向的内容*p可被改变)
const T* p (const修饰*p *p为不该被改动的对象)
STL迭代器:
std::vector<int> vec; const std::vector<int>::iterator iter = vec.begin(); //iter的作用像个T* const *iter = 10; //可以实现,改变的是所指物 ++iter; //错误!iter为const std::vector<int>::const_iterator cIter= vec.begin(); //cIter的作用像个const T* *cIter = 10; //错误!*cIter为const cIter++; //可以改变cIter
const成员函数
两个成员函数如果只是常量性(constness)不同,可以被重载。
logical constness,主张一个const成员函数可以修改他所处理的对象内的某些bits,但只有在客户端侦测不出的情况下才得如此。例如CTextBlock class有可能高速缓存(cache)文本区块的长度以便应付询问:
class CTextBlock { public: std::size_t length() const; private: char* pText; std::size_t textLength; //最近一次计算的文本区块长度 bool lengthIsValid; //目前的长度是否有效 }; std::size_t CTextBlock::length() const{ if (!lengthIsValid){ textLength = std::strlen(pText); //错误!在const成员函数内不能赋值 lengthIsValid = true; // 给textLength和lengthIsValid } return textLength; }
解决办法:利用C++的一个与const相关的摆动场:mutable(可变的)。mutable释放掉non-static成员变量的bitwise constness约束:
class CTextBlock { public: std::size_t length() const; private: char* pText; mutable std::size_t textLength; //这些成员变量可能总是会被改变 mutable bool lengthIsValid; //即使在const成员函数内 }; std::size_t CTextBlock::length() const{ if (!lengthIsValid){ textLength = std::strlen(pText); //现在这样就可以了 lengthIsValid = true; // } return textLength; }
在const和non-const成员函数中避免重复
class TextBlock{ public: const char& operator[](std::size_t position) const{ //边界检查(bounds checking) //志记数据访问(log access data) //检验数据完整性(verify data integrity) return text[position]; } char& operator[](std::size_t position){ //边界检查(bounds checking) //志记数据访问(log access data) //检验数据完整性(verify data integrity) return text[position]; } private: std::string text; }
以上有代码重复以及伴随的编译时间、维护、代码膨胀等问题。真正该做的是实现operator[]的机能一次并使用它两次。即在其中一个调用另一个。将常量性转除(casting away constness)
class TextBlock{ public: const char& operator[](std::size_t position) const{ //边界检查(bounds checking) //志记数据访问(log access data) //检验数据完整性(verify data integrity) return text[position]; } char& operator[](std::size_t position){ //现在只调用const op[] //边界检查(bounds checking) //志记数据访问(log access data) //检验数据完整性(verify data integrity) return const_cast<char&>( //将op[]返回值的const转除 static_cast<const TextBlock&>(*this) //为*this加上const [position] ); //调用const op[] } private: std::string text; }
这份代码有两个转型动作。在non-const operator[]内部若只是单纯调用operator[],会递归调用自己。所以必须明确的指出调用的是const operator[],但C++缺乏直接的语法可以这样做。因此这里将*this从原始类型TextBlock&转型为const TextBlock&。所以这里有两次转型:第一次用来为*this添加const(这使接下来调用operator[]时得以调用const版本),第二次从const operator[]的返回值中移除const。
反向做法(const成员函数调用non-const成员函数)是错误行为:因为对象有可能因此被改动。
- 将某些东西声明为const可帮助编译器侦测出错误用法。const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
- 编译器强制实施bitwise constness,但编写程序时应该使用“概念上的常量性”(conceptual constness)。
- 当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。
这篇关于[笔记]Effective C++ 条款3:尽可能使用const的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-29Elasticsearch慢查询日志配置
- 2024-05-29揭秘华为如此多成功项目的产品关键——Charter模板
- 2024-05-29海外IDC业务拓展的7大挑战
- 2024-05-29InLine Chat功能优化对标Github Copilot,CodeGeeX带来更高效、更直观的编程体验!
- 2024-05-29CodeGeeX 智能编程助手 6 项功能升级,在Visual Studio插件市场霸榜2周!
- 2024-05-29AutoMQ 生态集成 Apache Doris
- 2024-05-292024年IDC行业的深度挖掘:机遇、挑战与未来展望
- 2024-05-29五款扩展组件齐发 —— Volcano、Keda、Crane-scheduler 等,邀你体验
- 2024-05-29AutoMQ 对象存储数据高效组织的秘密: Compaction
- 2024-05-29活动预告|来 GIAC 大会听大数据降本利器:AutoMQ 基于云原生重新设计的 Kafka