const 完整使用规则

const的修饰规则(const便捷记忆法) 刚才转载了一篇文章《情景分析“C语言的const关键字”》,csdn上也有一篇《Const用法小结》,可能很多人看了这两篇文章之后就对const绝望了,太复杂了。其实const并不复杂,它是有规则的,不然设计语言的语法就不好弄了(大家看一下编译原理就好理解了)。下面就说一下我对const的理解:我觉得,语言里面的关键字,都有一个修饰域(即这个关键字修饰那块范围),还有一个修饰方向(即从那里开始 阅读详情

看到const 关键字,C++程序员首先想到的可能是const 常量。这可不是良好的条件反射。如果只知道用const 定义常量,那么相当于把火药仅用于制作鞭炮。const 更大的魅力是它可以修饰函数的参数、返回值,甚至函数的定义体。

const 是constant 的缩写,“恒定不变”的意思。被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。所以很多C++程序设计书籍建议:“Use const whenever you need”。

1.用const 修饰函数的参数

如果参数作输出用,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加const 修饰,否则该参数将失去输出功能。const 只能修饰输入参数:

如果输入参数采用“指针传递”,那么加const 修饰可以防止意外地改动该指针,起到保护作用。

例如StringCopy 函数:

void StringCopy(char *strDestination, const char *strSource);

其中strSource 是输入参数,strDestination 是输出参数。给strSource 加上const修饰后,如果函数体内的语句试图改动strSource 的内容,编译器将指出错误。

如果输入参数采用“值传递”,由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加const 修饰。

例如不要将函数void Func1(int x) 写成void Func1(const int x)。同理不要将函数void Func2(A a) 写成void Func2(const A a)。其中A 为用户自定义的数据类型。

对于非内部数据类型的参数而言,象void Func(A a) 这样声明的函数注定效率比较底。因为函数体内将产生A 类型的临时对象用于复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。

为了提高效率,可以将函数声明改为void Func(A &a),因为“引用传递”仅借用一下参数的别名而已,不需要产生临时对象。但是函数void Func(A &a) 存在一个缺点:

“引用传递”有可能改变参数a,这是我们不期望的。解决这个问题很容易,加const修饰即可,因此函数最终成为void Func(const A &a)。

以此类推,是否应将void Func(int x) 改写为void Func(const int &x),以便提高效率?完全没有必要,因为内部数据类型的参数不存在构造、析构的过程,而复制也非常快,“值传递”和“引用传递”的效率几乎相当。

问题是如此的缠绵,我只好将“const &”修饰输入参数的用法总结一下。

 

对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const 引用传递”,目的是提高效率。例如将void Func(A a) 改为void Func(const A &a)。

 

对于内部数据类型的输入参数,不要将“值传递”的方式改为“const 引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x) 不应该改为void Func(const int &x)。

2 用const 修饰函数的返回值
如果给以“指针传递”方式的函数返回值加const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。例如函数
const char * GetString(void);
如下语句将出现编译错误:
char *str = GetString();
正确的用法是
const char *str = GetString();
如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const 修饰没有任何价值。
例如不要把函数int GetInt(void) 写成const int GetInt(void)。
同理不要把函数A GetA(void) 写成const A GetA(void),其中A 为用户自定义的数据类型。
如果返回值不是内部数据类型,将函数A GetA(void) 改写为const A & GetA(void)的确能提高效率。但此时千万千万要小心,一定要搞清楚函数究竟是想返回一个对象的“拷贝”还是仅返回“别名”就可以了,否则程序会出错。
函数返回值采用“引用传递”的场合并不多,这种方式一般只出现在类的赋值函数中,目的是为了实现链式表达。

例如:
class A
{
A & operate = (const A &other); // 赋值函数
};
A a, b, c; // a, b, c 为A 的对象

a = b = c; // 正常的链式赋值
(a = b) = c; // 不正常的链式赋值,但合法
如果将赋值函数的返回值加const 修饰,那么该返回值的内容不允许被改动。上例中,语句 a = b = c 仍然正确,但是语句 (a = b) = c 则是非法的。
3 const 成员函数
任何不会修改数据成员的函数都应该声明为const 类型。如果在编写const 成员函数时,不慎修改了数据成员,或者调用了其它非const 成员函数,编译器将指出错误,这无疑会提高程序的健壮性。以下程序中,类stack 的成员函数GetCount 仅用于计数,从逻辑上讲GetCount 应当为const 函数。编译器将指出GetCount 函数中的错误。
class Stack
{
public:
void Push(int elem);
int Pop(void);
int GetCount(void) const; // const 成员函数
private:
int m_num;
int m_data[100];
};
int Stack::GetCount(void) const
{
++ m_num; // 编译错误,企图修改数据成员m_num
Pop(); // 编译错误,企图调用非const 函数
return m_num;
}
const 成员函数的声明看起来怪怪的:const 关键字只能放在函数声明的尾部,大概是因为其它地方都已经被占用了。
关于Const函数的几点规则:

a. const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数.
b. const对象的成员是不可修改的,然而const对象通过指针维护的对象却是可以修改的.
c. const成员函数不可以修改对象的数据,不管对象是否具有const性质.它在编译时,以是否修改成员数据为依据,进行检查.
e. 然而加上mutable修饰符的数据成员,对于任何情况下通过任何手段都可修改,自然此时的const成员函数是可以修改它的

const的修饰规则 const在*的左边,则指针指向的变量的值不可直接通过指针改变(可以通过其他途径改变); const在*的右边,则指针的指向不可变。简记为“左定值,右定向”。 (1)指针可以改变,指向的值不能改变     int a=10;     const int *p1=&a;    //例如:允许 p1+=1 ,不允许 *p1=20     int const *p2=&a;    ... 阅读详情

相关推荐

C++ mutable关键字赋予const成员函数修改成员变量的能力:在嵌入式系统中的应用

在const成员函数getTotalTime()中,我们返回totalTime的值,由于totalTime被声明为mutable,因此即使在const成员函数中,我们也可以修改它的值。总结起来,mutable关键字打破了const成员函数不可修改成员变量的特性,允许在const成员函数中修改被修饰为mutable的成员变量。然而,有时在嵌入式系统开发中,我们可能需要在const成员函数中修改某些特定的成员变量,以满足特定的需求。然而,在一些特殊情况下,我们可能需要在const成员函数中修改某些成员变量。

Orion_O的博客 288

夯实基本功——关于Const

看到const 关键字,C++程序员首先想到的可能是const 常量。这可不是良好的条件反射。如果只知道用const 定义常量,那么相当于把火药仅用于制作鞭炮。const 更大的魅力是它可以修饰函数的参数、返回值,甚至函数的定义体。const 是constant 的缩写,“恒定不变”的意思。被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。所以很多C++程序设

GoldenMan_cn的专栏 1907

《UE4游戏开发》之 《音效系统的实现》

音效系统需要负责管理什么事情: 1.1 确定声音控制的分类:如背景音乐、技能音效、界面音效、角色配音等,不同游戏对声音有不同的分类 1.2 控制每个分类的声音的开启与关闭,以及调节每个分类声音的大小 解决如何分类: 2.1 首先需要知道ue4为声音分类提供了什么:SoundClass通常需要一个根分类【SC_RPG_Master】,便于总体控制音效,以及指定引擎默认启动的音效 打开SoundClass资产【SC_RPG_Master】,对根控制的设置,将逐级传递并按比例进行设置,以此达到控制一类声音的目的.

qq_21919621的博客 2126

const修饰函数、返回值、参数(2.24)

因为上面说了形参在接收的时候是会创建一个临时变量的,那么对于传递的自定义类,他会new一个对象出来,这个对象调用构造函数构造,而在函数结束时还要调用析构函数析构,这样带来的开销就非常大了。以上,对于类的成员变量的修改,即使不是修改值,而是将成员变量从一个int型变为一个地址,这样也是一种对于成员变量的改变。而在const修饰的函数中,对于成员变量是给予了const属性的。而const成员函数只能调用const成员函数,对于非const函数,即使在函数内部没有修改成员变量,也不能被const函数所调用。

qq_44452887的博客 5594

FMT(基于rtthread)开源代码编译 win10下编译环境搭建及编译

FMT(基于rtthread)开源代码编译 win10下编译环境搭建及编译 什么是Firmament? Firmament (FMT) 是一款基于模型设计 (Model-Based-Design, MBD) 的开源自驾仪,可被用来快速构建无人机,无人车,无人船,机器人等平台的控制系统。 系统主要由两部分构成. FMT-Firmware: 一个基于C/C++开发的稳定、高性能的嵌入式系统. FMT-Model: 一个基于MATLAB/Simulink开发的仿真框架以及算法库. 昨天得知FMT开源飞控项目已经开

weixin_45786595的博客 2869

Crawl4AI实战:5分钟搞定电商价格监控爬虫(附Python代码)

本文详细介绍了如何利用开源AI网络爬虫框架Crawl4AI快速构建电商价格监控系统。通过Python实战代码,展示了从环境配置、智能内容提取到多平台适配、定时任务与数据可视化的完整流程,帮助运营人员和技术开发者高效实现自动化价格追踪与竞品分析。

weixin_29090917的博客 413

C++:类中const修饰的成员函数

const修饰的类成员函数

小青菜的博客 2990

Altium Designer 16安装教程(Windows11、小白教程)

Altium Designer 16在Windows11中的超详细安装教程

qq_47003770的博客 1万+

C++ const修饰函数、函数参数、函数返回值

const修饰函数 在类中将成员函数修饰为const表明在该函数体内,不能修改对象的数据成员而且不能调用非const函数。为什么不能调用非const函数?因为非const函数可能修改数据成员,const成员函数是不能修改数据成员的,所以在const成员函数内只能调用const函数。 #include <iostream> using namespace std; clas...

weixin_30500105的博客 2339

001、Zephyr RTOS简介与历史背景

本文介绍了Zephyr RTOS的特点及其在嵌入式开发中的应用。作者通过亲身经历比较了Zephyr与传统RTOS的差异,重点分析了Zephyr的设备树、统一驱动模型、基于CMake的构建系统、POSIX兼容层等核心特性。文章详细阐述了Zephyr在内核设计上的优势,如中断处理模型、内存管理等,并提供了社区生态和使用建议。作者建议开发者从简单项目入手逐步掌握Zephyr,同时指出了常见的使用问题和适用场景,认为Zephyr特别适合复杂软件架构的物联网和工业控制项目。

m0_50546716的博客 154

数据分享|1961-2017年中国0.25°×0.25° 逐日地表水文数据集(VIC-CN05.1)

其中,全球径流中心(University of New Hampshire and Global Runoff Data Centre, UNH/GRDC)的复合产流场集成了观测的河道径流和水量平衡模式模拟的地表和地下径流,常被用来评估模拟的径流。在长白山、海北灌丛和千烟洲通量站,模拟与观测的逐月潜热通量的平均NSE为0.61。VIC-CN05.1受益于较准确的大气驱动场、先进的地表水文参数化方案以及更真实丰富的土壤信息,可作为中国水文气象研究的参照数据,用于陆面模式的评估和长期的趋势分析等。

J_Giser的博客 1831

C++ const修饰符

C++ const修饰符

wkk的博客 551

华为OD机试 - 整型数组按照个位数排序(Python/JS/C/C++ 双机位C卷 100分)

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。给定一个非空数组(列表),其元素数据类型为整型,请按照数组元素十进制最低位从小到大进行排序,十进制最低位相同的元素,相对位置保持不变。当数组元素为负值时,十进制最低位等同于去除符号位后对应十进制值最低位。给定一个非空数组,其元素数据类型为32位有

学Java,找哪吒 399

[原创] [ 补充 ] 用 const 限定类的成员函数

原贴地址:http://bbs.chinaunix.net/viewthread.php?tid=300602 引用:原帖由 "yuxq" 发表:... 5. const 限定类的成员函数: class classname {  public:   int fun() const;  ..... }   注意:采用此种const 后置的形

tmdkq的专栏 508

构建OneService:打造高效、安全、灵活的企业级数据服务平台

数据服务(OneService)作为统一的数据服务出口,实现了数据的统一市场化管理,有效地降低数据开放门槛的同时,保障了数据开放的安全。

数据与算法架构提升之路专栏 2106

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【C++初阶】const 成员函数 & 取地址运算符重载超详解(六大默认成员函数收官篇)

本文主要讲解了C++中两个特殊的默认成员函数:const成员函数和取地址运算符重载。const成员函数通过修饰隐含的this指针,确保函数内不会修改对象内容,适用于只读操作,提高了代码的安全性和通用性。调用时需要遵循"权限只能缩小不能放大"的规则。取地址运算符重载通常由编译器自动生成,直接返回对象地址,实际开发中很少需要手动重载。关键点包括:const成员函数的本质是修饰this指针、调用时的权限规则、const在声明和定义时的写法一致性,以及取地址重载的两个版本(普通对象和const对象)

2301_82161965的博客 197

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Apache MXNet 混合精度(float16)训练实战指南:Gluon API 配置、性能优化与精度保障

本文基于 Apache MXNet 官方 FAQ 文档([docs/static_site/src/pages/api/faq/float16.md](https://link.gitcode.com/i/a8cac3a345e548e9c84f5010c35165c3))展开,系统讲解如何在支持 Tensor Cores 的硬件上,用 float16 混合精度训练深度神经网络:包括 Gluon

gitblog_00242的博客 413

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

C++ 函数书写规则

/ 函数原型返回类型必须匹配:return 语句的类型必须与函数声明的返回类型兼容参数类型必须明确:每个参数必须指定类型函数名唯一性:在同一作用域内,函数名和参数列表组成唯一的函数签名作用域规则:函数可以访问其所在作用域的变量,遵循作用域规则访问控制:类成员函数受 public、private、protected 访问控制这些规则构成了 C++ 函数书写的基础,理解它们对于编写正确的 C++ 代码至关重要。

FantasticOrange的博客 608

条款02:尽量以const, enum, inline替换#define

尽量少使用宏定义,如果ASPECT_RATIO被定义在一个非你所写的头文件内,为了追踪它会浪费很多时间。作为一个语言常量,AspectRatio肯定会被编译器看到,当然就会进入记号表内。对于浮点常量(比如本例),使用常量可能比使用#define导致更小量的码,因为预处理器“盲目地将宏名称ASPECT_RATIO替换为1.653”可能导致目标码(object code)出现多份1.653,如果改为常量AspectRatio绝不会出现相同的情况。 #define ASPECT_RATIO 1.653 //解决

SLAM小土堆 192

【C++】深入理解const成员

在C++中,const关键字是类型系统的重要组成部分,尤其在类成员的设计中扮演关键角色。通过合理使用const成员,开发者可以显著提升代码的健壮性、可维护性和安全性。本文将探讨const成员函数、const成员变量的核心特性和应用场景。

yishaobai的博客 721

C++——const详解

指针常量(顶层const): 本质是一个常量的指针,指针指向的地址不能改变,该地址存储的数据可以改变。常量指针(底层const): 指向常量的指针,,a是一个常量,p指向a的地址空间,a的值不能变,p的指向可以改变。更一般的,顶层const可以表示任意的对象是常量,对任何数据类型都适用,比如int、类、指针。 比较特殊的是:指针既可以是顶层const也可以是底层const,和其他类型有明显区别;const修饰变量主要有两个作用: 1、将变量定义为常量,保护被修饰的东西,防止意外的修改,增强程序的健壮性。co

kk阿彬 3万+

const的auto忽略规则

C++中这段代码会报错吗,为什么。

weixin_44344557的博客 654

C语言中const的详细用法及声明规则

前言本文主要涵盖了以下两部分的内容: 介绍了C语言中const的详细用法. 介绍了C/C++语言下声明语句的规则.

RuuuuuunNER 1万+

const iterator 和 const_iterator的区别

清晰明了 const iterator 和 const_iterator的区别

shylyly_的博客 906

C++函数前后加const的区别

1、函数前后const 函数前const:普通函数或成员函数(非静态成员函数)前均可加const修饰,表示函数的返回值为const,不可修改。格式为: const returnType functionName(param list) 函数后加const:只有类的非静态成员函数后可以加const修饰,表示该类的this指针为const类型,不能改变类的成员变量的值,即成员变量为read only...

Gorgeous_mj的博客 2万+

const修饰规则

将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数 隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。将d2传到Print函数里面时,它会用一个指向d2的指针来接收,而且这是默认非const的指针,所以由const保护的类传给非const的函数就是一个典型的权限放大问题。我们很容易发现,不管什么样的对象,都可以调用const修饰的成员函数,那是不是以后直接将所有的成员函数写成const修饰的?权限既可以缩小,也可以平移,就是不能放大。

2301_78139252的博客 376
上一篇: LXLT面试题-详解
下一篇: C++复习
devilkin64
博客等级 码龄19年 16粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值