(基本常识)C++中const与引用——面试常问

news2025/3/29 3:20:54

作者:求一个demo

版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

内容通俗易懂,没有废话,文章最后是面试常问内容(建议通过标题目录学习)

废话不多说,我们直接开始------>>>>>>

一、const关键字

        1、特点:

        ①用于定义常量,表示不可修改的值。

        ②可以应用于变量、函数参数、函数返回值、成员函数等。mutable修饰的成员变量可以在const成员函数中被修改。

class MyClass {
private:
    mutable int value;
public:
    void modifyValue() const {
        value = 10; // 正确:可以在 const 成员函数中修改 mutable 成员变量
    }
};

        ③提高代码安全性和可读性。

        2、示例:

// 1. const变量
const int MAX_SIZE = 100;
// MAX_SIZE = 200; // 错误:不能修改const变量

// 2. const指针
int value = 10;
const int* ptr1 = &value; // 指向const int的指针
// *ptr1 = 20; // 错误:不能通过ptr1修改值
ptr1 = nullptr; // 可以修改指针本身

int* const ptr2 = &value; // const指针,指向int
*ptr2 = 20; // 可以修改指向的值
// ptr2 = nullptr; // 错误:不能修改指针本身

// 3. const成员函数
class MyClass {
public:
    int getValue() const { // const成员函数,承诺不修改对象状态
        return value;
        // value = 10; // 错误:不能在const成员函数中修改成员变量
    }
private:
    int value = 0;
};

二、引用

        1、特点:

        ①引用是给变量取个别名,必须初始化,且不能重新绑定。

        ②没有独立的内存空间,与被引用变量共享同一内存。

        ③比指针更安全,不能为null。

        ④常用于函数参数传递和返回值。

        2、示例:

int main() {
    int x = 10;
    int& ref = x; // ref是x的引用
    
    ref = 20; // 修改ref等同于修改x
    std::cout << x; // 输出20
    
    int y = 30;
    // ref = y; // 不是重新绑定,而是把y的值赋给ref(即x)
    
    // 引用作为函数参数
    auto swap = [](int& a, int& b) {
        int temp = a;
        a = b;
        b = temp;
    };
    
    int a = 1, b = 2;
    swap(a, b); // 直接修改原变量
    std::cout << a << " " << b; // 输出2 1
}

三、const引用

        1、特点:

        ①不能通过引用修改被引用的对象。

int num = 10;
const int& ref = num;
ref = 20; // 错误,不能通过const引用修改被引用的对象
num = 20; // 正确,直接通过变量名可以修改

        ②可以绑定到临时对象、右值。

const int& ref1 = 5; // 合法,将const引用绑定到字面量5
const int& ref2 = int(10); // 合法,将const引用绑定到临时对象
int num = 10;
int& ref3 = num; // 合法
int& ref4 = 5; // 错误,普通引用不能绑定到右值

        ③常用于函数参数,避免不必要的拷贝同时防止修改。(下面第二条进行了详细解释)

#include <iostream>
#include <string>
using namespace std;

void printString(const string& str) {
    cout << str << endl;
}
int main() {
    string s = "Hello, World!";
    printString(s);
    return 0;
}

        2、注意:普通函数使用引用传递是为了避免对象拷贝,而拷贝构造函数使用引用传递是为了接收要被拷贝的对象,并且在函数体内部完成对象的拷贝操作。

#include <iostream>
using namespace std;

class MyClass {
public:
    int* data;
    // 构造函数
    MyClass(int value) {
        data = new int(value);
        cout << "Constructor called." << endl;
    }
    // 拷贝构造函数
    MyClass(const MyClass& other) {
        data = new int(*(other.data));
        cout << "Copy constructor called." << endl;
    }
    // 析构函数
    ~MyClass() {
        delete data;
    }
};

// 使用const引用作为参数的普通函数
void func(const MyClass& obj) {
    // 函数内部操作
    cout << "Value in func: " << *(obj.data) << endl;
}

int main() {
    MyClass obj(10);
    func(obj);
    return 0;
}

四、const、引用以及const引用的比较

        ①能否修改:const变量不能修改;引用可以修改,const 引用不能修改。

        ②能否重新绑定:const变量无绑定这一说;引用不能重新绑定;const引用不能重新绑定。

        ③是否需要初始化:const变量必须初始化;引用必须初始化;const引用必须初始化。

        ④能否绑定到临时对象:const变量无绑定这一说;引用不能绑定;const引用能绑定到临时对象。

        ⑤内存占用:const变量有独立内存;引用无独立内存;const引用无独立内存。

        ⑥主要用途:const变量用来定义常量;引用用来取别名、参数传递;const引用安全传递参数。

五、综合应用

        示例:

#include <iostream>
#include <string>
using namespace std;

class Student {
public:
    // const引用参数,避免拷贝同时防止修改
    Student(const string& name) : name(name) {}
    
    // const成员函数,承诺不修改对象状态
    const string& getName() const { return name; }
    
    // 返回const引用,避免拷贝同时防止外部修改
    const string& getConstRefName() const { return name; }
    
    // 返回普通引用,允许外部修改
    string& getRefName() { return name; }
    
private:
    string name;
};

void printStudent(const Student& s) {
    cout << "Student: " << s.getName() << "\n";
    // s.getRefName() = "NewName"; // 错误:s是const引用
}

int main() {
    const string name = "Alice";
    Student s(name);
    
    printStudent(s);
    
    // 通过引用修改
    s.getRefName() = "Bob";
    printStudent(s);
    
    // 尝试通过const引用修改
    const string& nameRef = s.getConstRefName();
    // nameRef = "Charlie"; // 错误:不能通过const引用修改
    
    // 临时对象
    printStudent(Student("Temp"));
}

六、constexpr与const区别

        1、constexpr

        (1)介绍:constexpr是C++11新特性,用于定义编译器常量和能在编译期求值的函数。

        (2)特点:

                ①表示值或函数在编译期就能确定。

                ②可用于变量、函数、构造函数等。

                ③C++17引入了if constexpr编译期条件判断。

        (3)用途:

                ①在编译期完成计算,而不是在运行期

constexpr int factorial(int n) {
    return (n <= 1) ? 1 : n * factorial(n - 1);
}

constexpr int fact5 = factorial(5);  // 编译时计算120
// 等价于直接写 constexpr int fact5 = 120;

                ②比#define宏更加安全。

constexpr int MAX_SIZE = 100;  // 替代 #define MAX_SIZE 100
int buffer[MAX_SIZE];          // 可用于数组大小

                ③可以在编译期构造和初始化对象

class Point {
public:
    constexpr Point(double x, double y) : x(x), y(y) {}
    constexpr double getX() const { return x; }
private:
    double x, y;
};

constexpr Point origin(0.0, 0.0);  // 编译期构造
constexpr double x = origin.getX(); // 编译期调用成员函数

        (4)示例:

constexpr int size = 10;  // 编译期常量
int arr[size];           // 可用于数组大小

// constexpr函数
constexpr int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

constexpr int fact5 = factorial(5);  // 编译期计算

        2、constexpr和const区别

        ①求值时机:const运行时常量(也可以是编译期确定);constexpr必须是编译期确定。

        ②初始化要求:const必须初始化;constexpr必须用常量表达式初始化,可以定义数组、结构体。

        ③函数应用:const不能保证编译期求值;constexpr可以在编译期求值。

        ④指针使用:const可以修饰指针本身或指向的内容;constexpr必须指向编译期确定的内存。

        ⑤主要用途:const运行时常量,保证不变性,不能作为模板参数;constexpr编译期计算,可以作为模板参数。

#include <iostream>
using namespace std;

int main()
{
    constexpr int num = 1 + 2 + 3;//constexpr也可换成const,这样下面url[num]也不报错
    int url[num] = {1,2,3,4,5,6};//如果上面不写constexpr,直接url[num],则会显示num不可用做常量
    couts<< url[1] << endl;
    return 0;
}

七、校招面试常问内容

1、const的作用的用法?

        ①定义常量:const int MAX = 100。

        ②保护函数参数不被修改:void func(const int other)。

        ③保护类成员不被修改:const成员函数。

        ④保护指针指向的内容:const char* p或char* const p。

2、const指针与指针const的区别?

const int* p1;    // 指向const int的指针,指针可变,内容不可变
int const* p2;    // 同上,等价写法
int* const p3;    // const指针,指向int,指针不可变,内容可变
const int* const p4;  // 指向const int的const指针,都不可变

3、const成员函数的作用是什么?能修改成员变量吗?

        ①不修改对象状态。

        ②不能修改非mutable成员变量

        ③可以被const对象调用。

4、指针和引用的区别?

        ①指针有自己的一块空间,而引用只是一个别名。
        ②使用sizeof看一个指针的大小,x32环境下4字节,x64环境下8字节;而引用则是引用对象的大小。
        ③指针在使用时可以指向其他对象,而引用只能是一个对象的引用,不能改变;指针有多级指针,而引用没有多级引用。
        ④指针和引用的++含义不同,指针++为整个类型++,引用++只是单纯+1.
        ⑤如果返回动态内存分配的对象或者内存,必须使用指针,引用可能引起内存泄漏。(因为返回动态内存分配的对象时,指针可以为null而引用不可以。如果使用动态分配的内存,当返回的引用超出作用域,无法释放内存,造成内存泄漏,而指针可以通过delete释放)
        ⑥作为参数传递的时候,指针需要被解引用才能对对象进行操作,而直接对引用的修改都会改变引用所指向的对象。(*解引用,然后才能访问对象,因为指针指向内存,引用指向对象)

5、为什么函数参数常用const引用?

        ①避免拷贝大对象的开销。

        ②防止意外修改传入的参数。

        ③可以接受临时对象(右值)。

6、函数返回引用时,需要注意什么?

        ①绝不能返回局部变量的引用(局部变量在函数内部定义,函数结束空间后内存空间被释放。如果返回局部变量的引用,在函数外使用该引用,访问的是不存在的内存空间)。

        ②可以返回成员变量、静态变量或传入参数的引用(成员变量是类的一部分,静态变量在整个程序运行期间都存在,传入参数的生命周期在函数调用期间都有效)。

7、const引用的特点?

        ①可以绑定到右值(临时对象)。

        ②可以延长对象的生命周期。

最后,如有不足和错误的地方,期待私信指正!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

dfs(深度优先)——太抽象了

1. 两种方法 #include<bits/stdc.h> using namespace std; //void dfs(int index,int n,vector<int> current) //{ // if(index>n){ // for(int i0;i<current.size();i){ // cout<<current[i]<<" "; // } // cout<<endl;…

python --face_recognition(人脸识别,检测,特征提取,绘制鼻子,眼睛,嘴巴,眉毛)/活体检测

dlib 安装方法 之前博文 https://blog.csdn.net/weixin_44634704/article/details/141332644 环境: python3.8 opencv-python4.11.0.86 face_recognition1.3.0 dlib19.24.6人脸检测 import cv2 import face_recognition# 读取人脸图片 img cv2.imread(r"C:\Users\123\…

redis解决缓存穿透/击穿/雪崩

文章目录 1.缓存穿透1.1 概念1.2 解决方案1.2.1 缓存空对象1.2.2 布隆过滤 1.2 店铺查询使用缓存穿透解决方案1.2.1 流程 2.缓存雪崩2.1 什么是缓存雪崩&#xff1f;2.2 雪崩解决方案 3.缓存击穿3.1 什么是缓存击穿&#xff1f;3.2解决方案3.2.1 基于互斥锁解决缓存击穿问题&am…

《TCP/IP网络编程》学习笔记 | Chapter 22:重叠 I/O 模型

《TCP/IP网络编程》学习笔记 | Chapter 22&#xff1a;重叠 I/O 模型 《TCP/IP网络编程》学习笔记 | Chapter 22&#xff1a;重叠 I/O 模型理解重叠 I/O 模型重叠 I/O本章讨论的重叠 I/O 的重点不在于 I/O 创建重叠 I/O 套接字执行重叠 I/O 的 WSASend 函数进行重叠 I/O 的 WSA…

python每日十题(10)

在Python语言中&#xff0c;源文件的扩展名&#xff08;后缀名&#xff09;一般使用.py。 保留字&#xff0c;也称关键字&#xff0c;是指被编程语言内部定义并保留使用的标识符。Python 3.x有35个关键字&#xff0c;分别为&#xff1a;and&#xff0c;as&#xff0c;assert&am…

LabVIEW液压振动锤控制系统

在现代工程机械领域&#xff0c;液压振动锤的高效与精准控制日益显得重要。本文通过LabVIEW软件&#xff0c;展开液压振动锤启停共振控制技术的研究与应用&#xff0c;探讨如何通过改进控制系统来优化液压振动锤的工作性能&#xff0c;确保其在复杂工况下的稳定性与效率。 ​ …

简单介绍My—Batis

1.什么是My—Batis&#xff1f; My—Batis是一个持久层框架&#xff0c;提供了sql映射功能&#xff0c;能方便的将数据库表和java对象进行映射&#xff0c;通过My—Batis可以将项目中的数据存储在数据库中&#xff0c;以便我们进行调用。值得注意的是My—Batis和spring不是一回…

ALTER TABLE SHRINK SPACE及MOVE的区别与适用场景

以下是 ‌Oracle 数据库‌中三个收缩表空间命令的对比&#xff1a; 1. ALTER TABLE table_name SHRINK SPACE;‌ ‌作用‌&#xff1a;直接重组表数据并移动高水位线&#xff08;HWM&#xff09;&#xff0c;释放未使用的空间到表空间‌。 影响‌&#xff1a; 会锁表&#…

docker远程debug

1. 修改 Java 启动命令 在 Docker 容器中启动 Java 程序时&#xff0c;需要添加 JVM 调试参数&#xff0c;jdk8以上版本 java -agentlib:jdwptransportdt_socket,servery,suspendn,address*:5005 -jar your-app.jar jdk8及以下版本&#xff1a; java -Xdebug -Xrunjdwp:tra…

rosbag|ROS中.bag数据包转换为matlab中.mat数据类型

代码见代码 msg_dict中设置自定义消息类型 test_config中设置需要记录的具体的值 test_config中topic_name以及message_type照搬plotjuggler打开时的参数 最后生成.mat文件在matlab中进行使用

pytest-xdist 进行高效并行自动化测试

pytest-xdist 的核心功能是通过多进程分发测试任务&#xff0c;每个进程独立运行测试&#xff0c;确保测试隔离。2025 年 3 月 25 日&#xff0c;pytest-xdist 在 GitHub 上已有超过 1,200,000 次下载&#xff0c;表明其在测试社区中的广泛接受。 在自动化测试中&#xff0c;随…

位置编码再思考

最近在做多模态&#xff0c;发现基于 transformer 的多模态&#xff0c;position embedding 是一个非常重要的内容&#xff0c;而且还没有统一方案&#xff0c;先暂做记录&#xff0c;几篇还不错的博客&#xff1a; Transformer学习笔记一&#xff1a;Positional Encoding&…

Deepseek API+Python 测试用例一键生成与导出 V1.0.3

** 功能详解** 随着软件测试复杂度的不断提升,测试工程师需要更高效的方法来设计高覆盖率的测试用例。Deepseek API+Python 测试用例生成工具在 V1.0.3 版本中,新增了多个功能点,优化了提示词模板,并增强了对文档和接口测试用例的支持,极大提升了测试用例设计的智能化和易…

[c语言日寄MAX]深度解析:大小端字节序

【作者主页】siy2333 【专栏介绍】⌈c语言日寄MAX⌋&#xff1a;这是一个专注于C语言刷题的专栏&#xff0c;精选题目&#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法&#xff0c;题目涉及的知识点全面覆盖&#xff0c;助力你系统提升。无论你是初学者&#xff0c;还…

Android ADB工具使用教程(从安装到使用)

目录 ADB工具介绍 什么是ADB&#xff1f; 组成 主要功能 ADB工具安装与连接设备 WIFI连接&#xff0c;提示计算机积极拒绝10061 WIFI成功连接后&#xff0c;拔掉数据线显示offline 提示adb版本不一致​编辑 ADB工具使用 ★日志操作命令 adb logcat:抓取日志 日志格式…

基于SSM框架的线上甜品销售系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以对于信息的宣传和管理就很关键。因此网上销售信息的…

Redis原理:Monitor 实现

在调用 Redis 的 MONITOR 命令后&#xff0c;可以在对应的客户端上实时查看服务器的执行情况。今天&#xff0c;我们将从源码的角度来深入探讨 MONITOR 机制是如何处理这些请求以及如何将数据反馈给用户的。 MONITOR 命令的实现 Redis 中所有命令的具体实现细节都可以在其源代…

计算机工具基础(七)——Git

Git 本系列博客为《Missing in CS Class(2020)》课程笔记 Git是一种分布式版本控制系统&#xff0c;被其跟踪的文件可被查询精细到行的修改记录、回退版本、建立分支等 模型 一般流程&#xff1a;工作区 → \to →暂存区 → \to →仓库(本地 → \to →远端) 工作区&#xff1…

23种设计模式-创建型模式-工厂方法

文章目录 简介场景问题1. 直接依赖具体实现2. 违反开闭原则3. 条件分支泛滥4. 代码重复风险 解决根本问题完整类图完整代码说明核心优势代码优化静态配置表动态策略 总结 简介 工厂方法是一种创建型设计模式&#xff0c;它提供了在父类中创建对象的接口&#xff0c;但允许子类…

142. 环形链表 II——考察数学,难!

142. 环形链表 IIhttps://leetcode.cn/problems/linked-list-cycle-ii/ 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,…