c++的const

const在C++中是一个非常重要的关键字,用于定义不可变的变量、函数参数、成员函数等。它可以提高代码的可读性、安全性,并帮助编译器进行优化。

  1. 定义常量

使用const定义不可变的变量:

const int MAX_SIZE = 100;
  1. 常量指针

指向常量的指针和常量指针有不同的用法:

const int* ptr1 = &MAX_SIZE; // 指向常量的指针
int* const ptr2 = &variable; // 常量指针
const int* const ptr3 = &MAX_SIZE; // 指向常量的常量指针
  1. 常量引用

常量引用用于避免不必要的复制,并且保证引用的值不会被修改:

void printValue(const int& value) {
    std::cout << value << std::endl;
}
  1. 常量成员函数

在类中,常量成员函数保证不会修改对象的成员变量:

class MyClass {
public:
    int getValue() const {
        return value;
    }

private:
    int value;
};
  1. 常量对象

定义一个常量对象,这个对象只能调用其常量成员函数:

const MyClass obj;
obj.getValue();
  1. 常量成员变量

在类中定义常量成员变量,这些变量必须在构造函数的初始化列表中初始化:

class MyClass {
public:
    MyClass(int v) : value(v) {}
    
    const int value;
};
  1. 常量静态成员变量

常量静态成员变量在类中定义,但必须在类外初始化:

class MyClass {
public:
    static const int MAX_VALUE;
};

const int MyClass::MAX_VALUE = 100;
  1. 常量函数参数

使用const修饰函数参数,表示参数在函数内部不会被修改:

void process(const int value) {
    // value 不能被修改
}
  1. 返回常量引用

返回常量引用以避免返回值被修改:

const std::string& getName() const {
    return name;
}
  1. 常量迭代器

使用常量迭代器来遍历容器,确保元素不会被修改:

std::vector<int> vec = {1, 2, 3, 4};
for (std::vector<int>::const_iterator it = vec.begin(); it != vec.end(); ++it) {
    std::cout << *it << std::endl;
}
  1. constexpr

constexpr在C++11中引入,用于定义在编译时计算的常量:

constexpr int getValue() {
    return 42;
}
constexpr int value = getValue();
  1. const_cast

const_cast用于移除或添加const属性,但应谨慎使用,避免违反常量性:

void modify(const int& value) {
    int& nonConstValue = const_cast<int&>(value);
    nonConstValue = 100;
}

这是一个名为modify的函数,它接受一个常量引用类型的整数参数value。

在C++中,常量引用(const reference)是对一个常量的引用。使用常量引用的主要目的是防止引用的对象被修改,同时允许该对象通过引用的方式传递,以避免复制大的对象。常量引用主要用于函数参数和返回值。

常量引用的语法

常量引用的语法如下:

const int& ref = someInt;

在这个例子中,ref是一个对整数someInt的常量引用。通过ref,可以读取someInt的值,但不能修改它。

使用常量引用的优点

  1. 防止修改:通过常量引用,可以确保函数不会修改传递给它的对象。例如:
    void printValue(const int& value) {
    std::cout << value << std::endl;
    // value = 10; // 这行代码将导致编译错误
    }

  2. 效率:常量引用可以避免对象的复制,尤其是对于大对象或自定义类型。通过引用传递而不是通过值传递,可以节省内存和时间。例如:
    void processLargeObject(const LargeObject& obj) {
    // 处理 obj 而不复制它
    }

  3. 兼容性:常量引用可以绑定到非常量对象和临时对象,因此使用常量引用可以使函数更加通用。例如:
    void showValue(const int& value) {
    std::cout << value << std::endl;
    }

    int main() {
        int a = 5;
        const int b = 10;
        showValue(a); // 绑定到非常量对象
        showValue(b); // 绑定到常量对象
        showValue(15); // 绑定到临时对象
    }
    

常量引用的限制

  1. 不可修改:通过常量引用,无法修改引用的对象。如果需要修改对象,则不能使用常量引用。
  2. 不能绑定到非常量指针:常量引用不能绑定到非常量指针,但可以绑定到非常量对象。

在C++中,int& value 和 int &value 实际上是完全相同的。两者都是对整数类型的引用,并且语法上没有区别。这种不同的书写方式只是个人编码风格的差异。更详细地解释一下。

引用的基本概念

引用(reference)是C++中的一种变量类型,允许创建对另一个变量的别名。定义一个引用时,使用&符号。例如:

int a = 10;
int& ref = a;

在这个例子中,ref是一个对整数变量a的引用,ref和a指向同一个内存位置,对ref的操作实际上是对a的操作。

不同书写方式的对比

int& value

int& value = someVariable;

这种方式将&符号紧贴在类型int上,表示value是一个整数引用。很多程序员喜欢这种写法,因为它清楚地表明了value的类型是“引用”。

int &value

int &value = someVariable;

这种方式将&符号紧贴在变量名value上,这在视觉上让人觉得&是变量名的一部分。有些程序员更喜欢这种风格,因为他们认为它更直观。

编译器的处理

无论使用哪种风格,编译器都会以相同的方式处理它们。int& value 和 int &value 都表示一个对整数类型的引用,二者之间没有任何功能上的差异。以下两个例子是完全等价的:

int a = 10;
int& ref1 = a;  // 引用声明方式1
int &ref2 = a;  // 引用声明方式2

ref1 = 20;
std::cout << a << std::endl;  // 输出20
ref2 = 30;
std::cout << a << std::endl;  // 输出30

综合实例

下面是一个综合使用const的例子:

#include <iostream>
#include <vector>

class MyClass {
public:
    MyClass(int v) : value(v) {}

    int getValue() const {
        return value;
    }

    const std::vector<int>& getValues() const {
        return values;
    }

    void addValue(const int& v) {
        values.push_back(v);
    }

private:
    const int value;
    std::vector<int> values;
};

int main() {
    const MyClass obj(10);
    std::cout << obj.getValue() << std::endl;

    obj.addValue(1); // 常量对象调用非常量成员函数是允许的,因为非常量成员函数不修改常量成员变量
    const std::vector<int>& values = obj.getValues();
    
    for (std::vector<int>::const_iterator it = values.begin(); it != values.end(); ++it) {
        std::cout << *it << std::endl;
    }

    return 0;
}

在这个综合实例中,展示了如何在类中使用const关键字来定义常量成员变量、常量成员函数、常量参数和常量引用。通过这些实践,可以编写出更加健壮和高效的C++代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/768699.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Chart.js四个示例

示例代码在图片后面&#xff0c;点赞加关注&#xff0c;谢谢 条形图 雷达图 折线图 圆环图 完整例子代码 具体代码在干什么看粗体加重的注释 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <me…

OceanBase Meetup北京站|跨行业应用场景中的一体化分布式数据库:AI赋能下的探索与实践

随着业务规模的不断扩张和数据处理需求的日益复杂化&#xff0c;传统数据库架构逐渐暴露出业务稳定性波动、扩展性受限、处理效率降低以及运营成本高等一系列问题。众多行业及其业务场景纷纷踏上了数据库现代化升级之路。 为应对这些挑战&#xff0c;7月6日&#xff0c;OceanB…

搭建个人博客及错误记录

搭建个人博客及错误记录 文章目录 搭建个人博客及错误记录需要用到的网址2.推荐两个参考教学视频3.发布一篇博客个人主题配置的提醒localhost拒绝连接问题解决办法ssh -T gitgithub.com失败问题解决Deployer not found:git解决 可以根据目录解决遇到的相同问题 需要用到的网址 …

德国威步的技术演进之路(下):从云端许可管理到硬件加密狗的创新

从单机用户许可证到WkNET网络浮点授权的推出&#xff0c;再到引入使用次数和丰富的时间许可证管理&#xff0c;德国威步产品不断满足市场对灵活性和可扩展性的需求。TCP/IP浮动网络许可证进一步展示了威步技术在网络时代的创新应用。借助于2009年推出的借用许可证以及2015年推出…

如何选择适合自己的笔记本电脑

在现代社会中&#xff0c;笔记本电脑已经成为人们工作、学习和娱乐的重要工具。然而&#xff0c;面对市场上琳琅满目的笔记本电脑产品&#xff0c;如何选择一款适合自己的笔记本电脑呢&#xff1f;本文将为您提供一些有用的建议。 首先&#xff0c;确定您的使用需求。不同的用户…

新手教学系列——慎用Flask-SQLAlchemy慢日志记录

在使用 Flask-SQLAlchemy 开发应用时,了解和避免潜在的问题是非常重要的。特别是在常驻进程和循环执行任务的场景下,慢查询记录功能(SQLALCHEMYRECORDQUERIES)可能会引发严重的内存泄漏问题。本文将详细介绍这个问题,并提供解决方案,帮助你在开发过程中避免掉入这些陷阱。…

为RK3568或RK3288开发板创建交叉编译环境{采用amd64的ubuntu系统配置交叉编译arm64开发环境}(保姆级包括安装QT)超详细记录版

为RK3568或RK3288开发板创建交叉编译环境{采用amd64的ubuntu系统配置交叉编译arm64开发环境}【保姆级包括安装QT】超详细记录版 Chapter1 为RK3568或RK3288开发板创建交叉编译环境{采用amd64的ubuntu系统配置交叉编译arm64开发环境}(保姆级包括安装QT)超详细记录版一. 安装QT程…

深入了解自动化:聊聊什么项目适合做自动化测试?

自动化测试 什么是自动化测 什么是自动化测试&#xff1f; 随着软件产业的不断发展&#xff0c;市场对软件周期的要求越来越高&#xff0c;于是催生了各种开发模式&#xff0c;如大家熟知的敏捷开发&#xff0c;从而对测试提出了更高的要求。此时&#xff0c;产生了自动化测试…

2024年港澳台联考考生成绩数据分析来啦

分数线 出炉 2024年的港澳台联考正式出分&#xff01;根据考生成绩&#xff0c;全国联招划档线如下&#xff1a; 一、本科批次 &#xff08;一&#xff09;普通类院校&#xff08;专业&#xff09;&#xff1a;文史类365分、理工类390分&#xff08;部分院校执行高分线&#…

算法基础入门 - 2.栈、队列、链表

文章目录 算法基础入门第二章 栈、队列、链表2.1 队列2.2 栈2.3 纸牌游戏2.4 链表如何建立链表?1.我们需要一个头指针(head)指向链表的初始。链表还没建立时头指针head为空2.建立第一个结点3.设置刚创建的这个结点的数据域(左半)和指针域(右半)4.设置头指针,头指针可方便…

10 - matlab m_map地学绘图工具基础函数 - 绘制多边形区域、流线图、散点图和添加注释的有关函数

10 - matlab m_map地学绘图工具基础函数 - 绘制多边形区域、流线图、散点图和添加注释的有关函数 0. 引言1. 关于m_patch2. 关于m_streamline3. 关于m_scatter4. 关于m_annotation5. 结语 0. 引言 本篇介绍下m_map中绘制多边形区域函数&#xff08;m_patch&#xff09;、绘制流…

数据库组成及原理

属性&#xff1a; 把数据库中的一个表类比成一个公司&#xff0c;那么公司里的每个人都是一个“属性”&#xff08;表中的一个字段视为一个属性&#xff09;&#xff0c;不管老板还是员工&#xff0c;只要是公司里的人&#xff0c;就都是一个属性。 主键&#xff1a; 老板就是“…

Docker安装PostgreSQL详细教程

本章教程,使用Docker安装PostgreSQL具体步骤。 一、拉取镜像 docker pull postgres二、启动容器 docker run -it --name postgres --restart always -e POSTGRES_PASSWORD=123456 -e

配置windows环境下独立浏览器爬虫方案【不依赖系统环境与chrome】

引言 由于部署浏览器爬虫的机器浏览器版本不同&#xff0c;同时也不想因为部署了爬虫导致影响系统浏览器数据&#xff0c;以及避免爬虫过程中遇到的chrome与webdriver版本冲突。我决定将特定版本的chrome浏览器与webdriver下载到项目目录内&#xff0c;同时chrome_driver在初始…

客户端渗透

1.一键可执行程序 2.给程序加壳 3.宏病毒感染文档 4.Android apk 利用 1.一键可执行程序 介绍&#xff1a;我们要进行客户端渗透&#xff0c;我们生成一个可执行程序&#xff0c;也是简单粗暴&#xff0c;MSF建立监听&#xff0c;把它发给受害者&#xff0c;只要受害者点击…

使用U盘重装系统

目录 一、 制作启动盘 1. 准备一个U盘和一台电脑 2. 下载win10安装包 二、安装操作系统 1. 插入系统安装盘 2. 通过进入BIOS界面进入到我们自己制作的启动盘上 三、安装成功后进行常规设置 一、 制作启动盘 1. 准备一个U盘和一台电脑 注意&#xff1a;提前备份好U盘内的…

15- 22题聚合函数 - 高频 SQL 50 题基础版

目录 1. 相关知识点2. 例子2.15 - 有趣的电影2.16 - 平均售价2.17 - 项目员工 I2.18 - 各赛事的用户注册率2.19 - 查询结果的质量和占比2.20 - 每月交易 I2.21 - 即时食物配送 II2.22 - 游戏玩法分析 IV 1. 相关知识点 函数 函数含义order by排序group by分组between 小值 an…

272. 最长公共上升子序列

Powered by:NEFU AB-IN Link 文章目录 272. 最长公共上升子序列题意思路代码 272. 最长公共上升子序列 题意 如题 思路 若按这个思路的话&#xff0c;代码为 O ( n 3 ) O(n^3) O(n3) for (int i 1; i < n; i ) {for (int j 1; j < n; j ){f[i][j] f[i - 1][j];…

如何使用ECharts和Java接口实现可视化的数据挖掘

如何使用ECharts和Java接口实现可视化的数据挖掘 【引言】 随着大数据时代的到来&#xff0c;数据挖掘成为了一项重要的技术&#xff0c;在企业决策、市场分析等领域发挥着重要作用。数据挖掘需要将大量的数据进行分析和展示&#xff0c;而可视化是一种直观、形象的展示方式。…

wasm的逆向之旅一

目录 概要 技术名词解释 1、WebAssembly 指令集概览 1)基本结构 2)数据类型 3)模块和函数 4)指令概览 1.i32 整数运算 2.i32 浮点数运算&#xff08;用法同整数运算&#xff09; 3.逻辑运算和位移(用法同整数运算) 4.内存访问指令 6.控制流指令 7.模块和导出指令 8.其他常…