Effective C++——尽可能使用const

2024-01-18 03:04

本文主要是介绍Effective C++——尽可能使用const,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        const允许指定一个语义约束(也就是指定一个“不该被改动”的对象),而编译器会强制实施这项约束。只要保持某个值不变是事实,就应该说出来。以获得编译器的协助,保证不被违反。

const与指针

        注意const的写法,

const char* p = ...;//p可以指向新的地址,但是不能通过*p修改值
char* const p = ...;//可以通过*p修改值,但是不能让p指向新的地址
void f1(const Widget* pw);
void f2(Widget const * pw);//两种写法是一样的

        STL的迭代器,以指针为根据,所以迭代器的作用就像个T*的指针。声明迭代器为const就像声明指针为const一样,表示这个迭代器不能指向不同的东西,但它所指的东西的值是可以改动的。

vector<int> vec;const vector<int>::iterator iter = vec.begin();//iter相当于一个T* const
*iter = 10;//可以,相当于改变*p的值
iter++;    //错误!
vector<int>::const_iterator cIter = vec.begin();//cIter相当于const T*
*cIter = 10;//错误!
cIter++;    //可以

注:关于auto关键字声明

for (auto it = myVector.begin(); it != myVector.end(); ++it) {// 使用 iterator
}for (auto it = myVector.cbegin(); it != myVector.cend(); ++it) {// 使用 const_iterator
}

const与函数声明

返回一个const

        令函数返回一个常量值,例如,

const int operator*(const MyClass& m1, const MyClass& m2);

为什么要返回一个常量呢?考虑如下情景

MyClass a,b,c;
if (a*b = c){...}

在本来应该是判断的过程中,变成了一个赋值过程,而且极大可能返回一个true。如果我们令a*b返回一个const值,就可以避免这种错误的发生(编译就不会通过,尽早发现错误)。

const成员函数

        将const实施于成员函数的目的,是为了确认该成员函数可以作用于const对象身上。第一,它们使class接口容易理解。方便得知哪个函数可以改动对象内容而哪个函数不行。第二,它们使“操作const对象”成为可能。

        一个容易被忽视的事实是:两个成员函数如果只是常量性不同,可以被重载

class TextBook{
private:string text;
public:const char& operator[](size_t position) const{ return text[position];}char& operator[](size_t position){ return text[position];}
};

        其中,const的方法可以被const对象调用。例如,

void print(const TextBook& tb){...cout << tb[0];...
}

注,

const void f(...) const;

第一个const说明函数的返回值是const,第二个const声明f函数不会修改对象值,可以被const对象调用(但可以修改static成员变量)

mutable关键字

        mutable修饰的non-static成员变量,在const成员函数中也可以修改其值。(某些场景可能确实需要如此)

在 const 和 non-const 成员函数中避免重复

        如果,一个代码量很多的成员函数,同时需要一个const版本也需要一个non-const版本,则必然会出现大量的重复代码。

class TextBook{
private:string text;
public:const char& operator[](size_t position) const{//DO A//DO B//DO Creturn text[position];}char& operator[](size_t position){//DO A//DO B//DO Creturn text[position];}
};

        在上面的代码中,const 版本做到了 non-const 版本的一切,除了一个const资格修饰。我们将代码做如下修改:

class TextBook{
private:string text;
public:const char& operator[](size_t position) const{//DO A//DO B//DO Creturn text[position];}char& operator[](size_t position){return const_cast<char&>(static_cast<const TextBook&>(*this)[position]);}
};

        这份代码有两个转型动作,而不是一个。我们让 non-const 调用 const,但 non-const 内部如果单纯调用operator[],会递归调用自己。所以,为了避免无穷的递归,我们必须明确指出调用的是const operator[],但C++没有明确的语法可以这么做。因此,将 (*this) 从原始类型转型为 const TextBook& ,调用operator[]后,再将返回值中移除 const。

static_cast强迫隐式转换,为*this加上const

const_cast 将返回值的const char& 的const去掉

        运用 const 成员函数实现出其 non-const 孪生兄弟 的技术。而反向做法,“const成员函数调用non-const成员函数”是一种错误行为!

这篇关于Effective C++——尽可能使用const的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/617920

相关文章

C++右移运算符的一个小坑及解决

《C++右移运算符的一个小坑及解决》文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数... 目录我遇到了这么一个www.chinasem.cn函数由此可以看到也很好理解总结我遇到了这么一个函数template<typename T>unsigned

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有