【C++】尽可能使用const

C++ const使用详解 在主函数main()里,标识符gc的值在编译期间是不知道的,这也意味着需要存储空间,但是初始化要在定义点进行,而且一旦初始化,其值就不能改变,我们发现c2是由gc计算出来的,它的作用域与其他类型const的作用域是一样的,这是对#define用法的一种改进。如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。const同样运用于类中,但是它的意义又有所不同,我们可以创建const的数据成员,const的成员函数,甚至是const的对象,但是保持类的对象为const比较复杂, 阅读详情

指针、迭代器与const的关系

1.  如果关键字出现在星号左边,表示被指物是常量;如果出现在星号右边,表示指针自身是常量;如果出现在星号两边,表示被指物和指针两者都是常量。如果被指物是常量,把 const 写在类型之前或者类型之后、星号之前是一样的。
2.  迭代器的作用就像 T* 指针,const 在迭代器前,迭代器不能改变,即声明一个 T* const 指针;const 在迭代器变量前,迭代器所指变量不能变,即声明一个 const T* 指针,需要用 const_iterator。
    vector<int> vec;
    const vector<int>::iterator iter = vec.begin(); 
    //iter就像个T* const
    *iter = 10;     //right
    ++iter;         //iter不能变

    vector<int>::const_iterator cIter = vec.begin();
    //cIter就像个const T*
    *cIter = 20;    //*cIter 不能变
    cIter++;        //right

面对函数声明时的const

const与函数返回值

令函数返回一个常量值,往往可以降低因客户错误而造成的意外,而又不至于放弃安全性和高效性。

const与函数参数

除非需要改动参数或者 local 对象,否则将参数声明为 const


const成员函数

目的:确认该成员函数可以作用于const对象身上。
为什么?
1.  使class接口容易被理解,可以得知哪个函数可以改动对象内容而哪个函数不行
2.  可以操作const对象,const成员函数可用来处理取得的const对象,也可以操作non-const对象

PS:两个成员函数如果只是常量性不同,那么也可以被重载。

class TextBlock
{
public:
    TextBlock(string str)
    {
        text = str;
    }
    const char& operator[] (size_t position) const
    {
        cout << "call const" << endl;
        return text[position];
    }

    char& operator[] (size_t position)
    {
        cout << "call non-const" << endl;
        return text[position];
    }


private:
    string text;
};

int main()
{
    TextBlock tb("Hello");
    cout << tb[0] << endl;//调用non-const
    tb[0] = 'X';    //right           


    const TextBlock ctb("World");
    cout << ctb[0] << endl;//调用const
    //ctb[0] = 'X';  //error 写一个const对象
    return 0;

程序输出:

这里写图片描述

还要注意,`non-const operator[]` 返回类型是 `char&`  **如果返回类型是个内置类型,那么改动函数返回值从来就不合法**。即使合法,那么按照pass by value返回,改变的也只是对象的一个副本,而没有改变对象本身。
成员函数是const意味着什么?

两个流行概念:bitwise constness和logical constness

bitwise constness

是C++对常量性的定义,const成员函数不可以更改对象内任何non-static成员变量。
一个更改了“指针所指物”的成员函数虽然不能算是const,但如果只有指针隶属于对象,而指针所指对象不属于对象,那么称此函数为bitwise constness编译器不会有异议。

using namespace std;
class CTextBlock
{
public:
    CTextBlock(const char text[])
    {
        pText = (char*)malloc(sizeof(char)*strlen(text));
        strcpy(pText,text);
    }
    char& operator[] (size_t position)const
    {
        return pText[position];
    }
private:
    char *pText;
};

int main()
{
    const CTextBlock cctb("Hello");
    char* pc = &cctb[0];
    *pc = 'J';
    cout << cctb[0] << endl;
    return 0;
}

operator实现代码并不更改pText,编译器认定它是bitwise constness。创建了一个常量对象,并设初值,而且只对它调用const成员函数,但是cctb的成员内容变成了”Jello”,终究还是改变了它的值。

logical constness

一个const成员函数可以修改它所处理的对象内的某些bits,但只有在客户端侦测不出的情况下才得如此。

class CTextBlock
{
public:
    CTextBlock(const char text[])
    {
        pText = (char*)malloc(sizeof(char)*strlen(text));
        strcpy(pText,text);
    }
    size_t length() const;
private:
    char *pText;
    size_t textLenght;      //最近一次计算的文本区块长度
    bool lengthIsValid;     //目前的长度是否有效
};
size_t CTextBlock::length() const
{
    if(!lengthIsValid)
    {
        textLenght = strlen(pText);  //error  
        lengthIsValid = true;       //在const成员函数内不能给对象成员赋值
    }
    return textLenght;
}

成员函数length()当然不是bitwise const,因为textLength和lengthIsValid都可能被修改。但是编译器坚持认为是bitwise const,因此出现 error。

解决方法:利用C++的一个与 const 相关的摆动场:mutable(可变的)。mutable 释放掉 non-static 成员变量的 bitwise constness 约束。
比如上例中改为:

mutable size_t textLength;
mutable bool lengthIsValid;

这样在const成员函数内,这些变量也可被更改。

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

比如const完全和non-const版本做的工作一样,只是其返回类型多了一个const资格修饰。这时候我们想的是实现这个功能一次并使用两次,也就是说必须令其中一个调用另一个。

那么谁调用谁呢?

const 成员函数调用 non-const 成员函数是一种错误行为,因为对象有可能因此被改动;而反向调用是安全的,non-const成员函数本来就可以对其对象做任何动作,所以在其中调用一个const成员函数并不会带来风险。

还是以 class TextBlock为例:

/* const 和以前一样*/
const char& operator[] (size_t position) const
    {
        ...
        ...
        ...
        return text[position];
    }

/* non-const 调用 const operator[]*/
    char& operator[] (size_t position)
    {
        return 
        const_cast<char&>(
            static_cast<const TextBlock&>(*this)
            [position]
        );
        return text[position];
    }

两次转型:
1. 将自身*this从原始类型TextBlock&转型为const TextBlock&,使用 static_cast为*this加上const;
2. 从const operator[]的返回值中移除const,用const_cast。

请记住:
1.  将某些东西声明为const可帮助编译器侦测出错误用法。const 可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
2.  编译器强制实施bitwise constness,但编写程序时应该使用“概念上的常量性”。
3.  当 const 和 non-const 成员函数有着实质等价的实现时,令non-const 版本调用 const 版本可避免代码重复。
CPP使用const的情况 那么常量引用和非常量引用可能会导致不同的函数(例如拷贝构造函数和拷贝赋值运算符)被调用,因此在这些情况下,选择使用常量引用还是非常量引用是非常重要的。 阅读详情

相关推荐

C++ Const使用总结

C++中const关键字的作用与使用技巧 const是C++中的重要关键字,主要用于定义常量、保护数据不被修改以及提高程序健壮性。其核心作用包括:1.定义类型安全的常量;2.防止意外修改数据;3.优化程序效率(编译器将const常量保存在符号表中);4.支持函数重载;5.节省内存空间。const可以修饰变量、指针、函数参数、返回值以及类成员,使用时需注意:指针const的位置决定修饰对象(内容或指针本身);类const成员必须在初始化列表赋值;const对象只能调用const成员函数。开发中应合理使用con

程序猿老樊的博客 998

const iterator 和 const_iterator的区别

清晰明了 const iterator 和 const_iterator的区别

shylyly_的博客 905

.NET适配HarmonyOS进展 1. 前言

目前国产化系统浪潮下,适配鸿蒙是中国软件大势所趋,.NET作为最适合开发客户端语言之一,适配鸿蒙系统(HarmonyOS Next)是目前.NET开发者最关心的事情。我目前业余时间正在移植Avalonia到HarmonyOS,去年在.NET Conf CN上分享过,目前又取得一点进展,所以本文把所有问题进行整合与大家进行分享。

2301_76476890的博客 1461

C++守则——尽可能使用const

const不管放在哪都是 表示此值不可被修改,此外还需要区别的就是const是修饰指针还是修饰数值:在*号前是指针所指的数值不可被修改,称为底层const,*号后面表示是指针不可被修改,称为顶层const。我们看的是const是在*的左边还是右边,与其在变量类型的那边并没有多大的关系,完全看个人习惯例如: const int *p; int const *p; const 最具威力的用法是面对函...

qq_43419761的博客 242

工业数据采集实战:用open62541库读写PLC的OPC UA节点(避坑指南)

本文详细介绍了如何使用open62541库实现工业PLC的OPC UA节点数据采集,涵盖环境搭建、节点读写优化及生产环境故障排查。通过订阅模式和多节点读写技术,显著提升数据采集效率与稳定性,适用于智能制造和工业物联网场景。

weixin_30598225的博客 398

Jetson AGX Orin 新手避坑:解决‘找不到nvidia-jetpack包’的完整修复指南

本文详细介绍了Jetson AGX Orin设备在安装JetPack开发套件时遇到的'nvidia-jetpack包缺失'问题的完整解决方案。通过分析问题根源、提供分步修复指南以及系统优化建议,帮助开发者快速解决这一常见问题,充分发挥Jetson AGX Orin的边缘计算性能。

weixin_42520909的博客 460

C++const四种用法

一、用const修饰函数参数1、修饰指针,可以防止指针被修改void test(const ClassA* a) { ClassA** b = &a; //编译错误,不能对const指针取地址 ClassA* c = a; //编译错误,不能将const指针转普通指针 (*b) = new ClassA(); } void test2(ClassA* a) { Cla

游戏猫的博客 1万+

基于开源项目构建 CFS(网络靶场实战演练)平台

摘要:构建CFS网络靶场可使用多个开源组件组合,包括EVE-NG/GNS3或ContainerLab构建网络环境,Kasm提供工作空间,CALDERA+Atomic Red Team实现攻击模拟,DetectionLab建立防御环境,Malcolm/Arkime进行流量监控,CyRIS提供编排框架,Vulhub/DVWA创建漏洞靶标。关键在于通过API深度集成各组件,同时需注重安全隔离、资源规划及维护成本。建议开发统一管理平台,结合Ansible/Terraform实现自动化部署,打造定制化实战演练环境。(

深山技术宅的博客 1842

EffectiveC++详解:条款03-尽可能使用 const

文章目录条款03-尽可能使用 `const`1. 复习 `const` 的用法2. 函数返回常量可以减少错误3. `const` 成员函数4. 两个流行概念 bitwise constness 、logical constness4.1 bitwise constness4.2 logical constness5. 在 `const` 和 `non-const` 成员函数中避免重复6. 总结 ...

神奇小海螺的博客 5034

Lasso的原理及其与其他特征选择方法的比较进行阐述,然后讨论Lasso优点、缺点以及应用场景,最后给出了代码实例

在机器学习领域中,特征选择(feature selection)是指在模型训练前对数据集进行分析,选择其中有助于预测目标变量或影响模型性能的特征,去除不相关或冗余的特征,提升模型的泛化能力。而Lasso回归是一种很流行的用于特征选择的方法之一。Lasso回归(又称LASSO,least absolute shrinkage and selection operator)是一种线性模型中的特征选择方法。

AI天才研究院 3050

海洋CMS admin_notify.php 远程代码执行漏洞复现(CVE-2024-30565)

海洋CMS admin_notify.php 接口处存在远程代码执行漏洞,经过身份验证的远程攻击者可利用该漏洞执行任意代码,写入后门文件,进而控制整个web服务器。

0xSec 2712

条款03:尽可能使用const

目录 1. 总结 2. const对象 3. const函数返回值和函数参数 4. const成员函数 const成员函数的重要性 bitwise constness logical constness 5. 在const和non-const成员函数中避免重复 1. 总结 const可用于...

技术研究中心 384

图解ADAS电源系统架构:看懂这张图,搞懂前装摄像头的供电秘密!

别以为ADAS系统就是“摄像头 + SoC”,其实最难搞的是供电系统,尤其是要满足车规级ASIL-D安全等级时。供电时序、电压稳定性、电源监控、冗余通信链路,一个都不能少。😤一旦电源选型不对,轻则系统卡顿,重则全车失控,不是闹着玩的。

weixin_43199439的博客 671

如何跨文件使用C++中的const类型指针

通过二个文件:main.cpp , fun.cpp 来测试const类型指针的跨文件使用// main.cpp#include char * const str=new char[100];void fun();void main(){     strcpy(str,"hello");     fun();} // fun.cpp#include

shi_hang_nk的专栏 856

关于机器人精度的总结(重复精度和绝对精度区分)

机械臂是工业生产中的重要设备,在焊接码垛 以及 非 接触测量等 领域中有 着重要应 用。然而由于机械臂本体制造中存在机械制造公差装配误差导致的运动学参数误差以及电机转角与关节转角间减速比误差等,导致机械臂存在。因此需要对机械臂进行标定,提高机械臂的绝对定位精度。ABB系列某款机器人精度参数表。

大胡子大叔的专栏 1万+

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

[C++]const的使用场景

const修饰指针有三种情况:1.const修饰指针 -- 常量指针2.const修饰常量 -- 指针常量3.const即修饰指针,又修饰常量总结:我的理解:const就是让这个单元格的内容不可以被修改,const右边的那格变量的值不可以被修改。比如:const int *p = &stiA;(这里理解为,p是一个指向int的指针,在别的地方可以写为int* p,更加强调一个整体类型)就是说,这个指针p指向的int值是不可以被修改的)。但是对于 int * const p = &sti2A;

qq_74776071的博客 971

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

C++中const的使用

/ 推荐使用大写命名。

KodeScape 623

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

C++ const用法 尽可能使用const

原文地址   C++ const 允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的。如果在编程中确实有某个值保持不变,就应该明确使用const,这样可以获得编译器的帮助。 1.const 修饰成员变量 复制代码 1 #include 2 using namespace std; 3 int main(){ 4 int a1=3; ///non-con...

liuhongyi0104的博客 304

C++ const 使用

const在 API 设计中,尽可能在函数参数、方法和非局部变量上使用const,以提供清晰且编译器验证的文档。const有助于区分读写操作,是线程安全代码的关键。选择const的位置时,优先考虑可读性和一致性。对于编译期常量,考虑使用constexpr替代const。希望这些讲解对你理解const的使用有所帮助!如果有具体代码示例需要分析,可以告诉我,我会进一步解释。

cxyhjl的博客 856

C++ const的使用

摘要 在C++中,const可以用在很多的场合,本文尝试说明const常用的几种场景,并解释为什么要这样使用。 const的含义 在进行讨论之前,先说明const是个什么东西。 const其实是一个语义约束,告诉编译器和其他程序员某值应该保持不变。在程序编译的过程中该约束由编译器保证,如果违反了const约束,编译报错。 函数形参数列表 最常使用const的大概就是在函数的参数列表了吧,如: int max(const int a, const int b); 通常应该将函数的参数声明为const,告诉编

689

C++中const使用总结

原文链接 https://blog.youkuaiyun.com/Eric_Jo/article/details/4138548 C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助。 Const 是C++中常用的类型修饰符,常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。 一、Const作用 如下表所示: No. 作用 ...

l15799033407的博客 198

【C++中的const函数】何时与如何正确声明使用C++ const函数

在C++编程中,`const`(常量)是一个我们经常遇到的关键字。它为我们提供了一种强大的工具,帮助我们编写更安全、更可读的代码。但是,为什么我们需要这样的工具?为什么我们不能只依靠自己的直觉和经验来编写代码呢?

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 686

C++中我如何合理使用const和constexpr?

constexpr所限定的变量必须是编译阶段完成的变量,当我们用非编译阶段完成的变量给constexpr限定的指针赋值时,便会发成错误。的 “条款3:尽可能使用const” 就指出const在指针运用中约束的不同——如果关键字const出现在星号左边,表示被指物是常量;使用constexpr限定的函数实际上是将函数在编译过程中转换为常量表达式,在其中加入复杂语句,可能会导致常量表达式转换失败。除非有非得使用const的情况发生,否则可使用const的地方,一律可改为使用constexpr。

2401_82410644的博客 1111

C++ const 关键字的使用总结

const 关键字的详细使用总结

编程猿来如此 576

c++-const_cast 使用

C++提供了四个转换运算符: const_cast (expression) static_cast (expression) reinterpret_cast (expression) dynamic_cast (expression)一、const_cast (expression) const_cast转换符是用来移除变量的const或volatile限定符。 1.1**用

扎扎实实写代码的专栏 3158
上一篇: 预处理器、编译器、汇编、链接
下一篇: PV原语小结及进程同步示例
Tanswer_
博客等级 码龄11年 231粉丝 91原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值