C++常见概念问题(2)

news2024/9/24 0:21:03

C++常见概念问题(2)

C++中异常处理

➢ 异常处理过程:
在执行程序发生异常,可以不在本函数中处理,而是抛出一个错误信
息,把它传递给上一级的函数来解决,上一级解决不了,再传给其上一级,
由其上一级处理。如此逐级上传,直到最高一级还无法处理的话,运行系统
会自动调用系统函数 terminate,由它调用 abort终止程序。这样的异常处
理方法使得异常引发和处理机制分离,而不在同一个函数中处理。这使得底
层函数只需要解决实际的任务,而不必过多考虑对异常的处理,而把异常处
理的任务交给上一层函数去处理。
➢ 异常处理机制的组成:try(检查),throw(抛出),catch(捕获)。
把需要检查的语句放在 try 模块中,检查语句发生错误,throw 抛出异
常,发出错误信息,由 catch 来捕获异常信息,并加以处理。一般 throw
抛出的异常要和 catch 所捕获的异常类型所匹配。

右值引用,移动语义,完美转发

右值(Rvalue):表示一个临时的、不能被取地址的值,通常是一个字面量、临时对象或表达式的结果。右值只能出现在赋值语句的右边。
右值引用:右值引用通过&&符号表示,它主要用于绑定到临时对象(即右值),从而允许程序员更高效地管理资源。

为什么要右值引用

  1. 如果只能左值引用,要使用一个对象的副本时,需要进行深拷贝,需要资源复制开销较大;右值引用允许直接绑定到临时对象(右值),这样就可以定义特殊的构造函数和赋值运算符,这些构造函数和赋值运算符可以“移动”而非复制资源。这种操作通常称为移动构造和移动赋值。移动操作通常比复制操作要快,因为它们可以避免不必要的资源复制,例如,直接传递动态内存的指针而不是复制整个数组。

移动语义

当编译器看到&&的时候会判定为右值引用,对编译器来说这是一个临时变量的标识,对于临时变量来说我们仅仅做一次浅拷贝就行,不需要深拷贝,从而解决了前面提到的临时变量拷贝构造产生的性能损失的问题。这就是所谓的移动语义,右值引用的一个重要作用是用来支持移动语义的。

完美转发

右值引用的另一个用途是实现完美转发。完美转发允许函数模板接收任意类型的参数(包括左值和右值),并将参数转发给另一个函数,同时保持参数的原始属性(左值或右值)。

这在编写通用的库函数时非常有用,因为它允许函数透明地转发参数,使得库函数的用户不必关心参数是左值还是右值。

例如:

template<typename T>
void wrapper(T&& arg) {
    process(arg);  // 这里直接传递会导致错误的左值/右值属性
    process(std::forward<T>(arg));  // 正确的完美转发
}

在这个例子中,forwardValue使用右值引用和std::forward来完美转发其参数给processValue函数。

explicit 关键字有什么用

explicit 关键字在 C++ 中用于控制构造函数和转换函数的隐式调用。它的主要作用是防止编译器进行隐式类型转换,从而提高代码的安全性和可读性。

有了malloc/free为什么还要new/delete?

mallocfree是C语言标准库中的函数,用于动态内存管理。newdelete是C++语言中的运算符,它们同样用于动态内存管理,但与mallocfree相比,它们提供了一些额外的特性和优势:

  1. 类型安全

    • new可以自动进行类型检查,确保分配的内存用于正确的类型。如果尝试分配一个错误的类型,编译器会报错。
    • malloc不进行类型检查,因此如果传递给malloc的指针类型不正确,可能会导致运行时错误。
  2. 异常处理

    • 在C++中,new可以抛出异常,如果内存分配失败,可以通过std::bad_alloc异常来处理。这使得内存分配失败时的错误处理更加灵活。
    • malloc在分配失败时返回NULL,调用者需要检查返回值来处理错误。
  3. 构造函数调用

    • 使用new分配内存时,会自动调用对象的构造函数来初始化新分配的对象。
    • malloc只分配内存,不会调用任何构造函数。
  4. 析构函数调用

    • 当使用delete删除对象时,会自动调用对象的析构函数来释放对象资源。
    • free仅释放内存,不会调用析构函数。
  5. 引用计数

    • 在C++中,使用new[]delete[]进行数组内存管理时,会自动处理引用计数,防止内存泄漏。
    • mallocfree不提供这种机制,需要手动管理数组的生命周期。
  6. 兼容性

    • newdelete是C++的一部分,它们在C++程序中提供了一致的内存管理模型。
    • mallocfree是C语言的一部分,在C和C++程序中都可以使用,但它们不是C++类型系统的一部分。
  7. 智能指针

    • C++中的智能指针(如std::unique_ptr, std::shared_ptr等)使用newdelete进行内存管理,提供了更高级的内存管理功能,如自动资源管理、异常安全等。

移动构造函数

**移动构造函数:**有时候我们会遇到这样一种情况,我们用对象a初始化对象b后对象a我们就不在使用了,但是对象a的空间还在呀(在析构之前),既然拷贝构造函数,实际上就是把a对象的内容复制一份到b中,那么为什么我们不能直接使用a的空间呢?这样就避免了新的空间的分配,大大降低了构造的成本。这就是移动构造函数设计的初衷。拷贝构造函数中,对于指针,我们一定要采用深层复制,而移动构造函数中,对于指针,我们采用浅层复制。
但是指针的浅层复制是非常危险的。浅层复制之所以危险,是因为两个指针共同指向一片内存空间,若第一个指针将其释放,另一个指针的指向就不合法了(pointer dangling)。所以我们只要避免第一个指针释放空间就可以了。避免的方法就是将第一个指针(比如a->value)置为NULL,这样在调用析构函数的时候,由于有判断是否为NULL的语句,所以析构a的时候并不会回收a->value指向的空间(同时也是b->value指向的空间)

为什么拷贝构造函数必须是引用?

为了防止递归调用。

如果不用引用,就会是值传递的方式,但是值传递会调用拷贝构造函数生成临时对象,从而又调用一次拷贝构造函数。就这样无穷的递归下去。

如果是指针类型

就变成了一个带参数的构造函数了。。。

比如A(A* test)

被free回收的内存是立即返还给操作系统吗

被free回收的内存会首先被ptmalloc使用双链表保存起来,当用户下一次申请内存的时候,会尝试从这些内存中寻找合适的返回。这样就避免了频繁的系统调用,占用过多的系统资源。同时ptmalloc也会尝试对小块内存进行合并,避免过多的内存碎片

向上类型转换和向下类型转换

**向上类型转换:**upcast,把派生类的指针或引用转换成基类的指针或者引用是安全的(或者说基类指针指向派生类);因为用转换后的指针只能访问基类部分的函数时候,都可以访问,肯定安全。这个是隐式转换,c++认为是安全的。

**向下类型转换:**downcast,把基类指针或引用转换成派生类表示(或者说把派生类指针指向基类)时,由于没有动态类型检查,所以是不安全的。如果转换后的指针访问派生类新增加的函数,这个时候基类中本来没有这个函数,那就会出错。

很形象,向上就是派生类指针变成基类指针,向下就是基类指针变成派生类指针。

内存泄漏?出现内存泄漏如何调试?

内存泄露一般指的是堆内存的泄露,即用户自己开辟的内存空间。应用程序使用malloc、realloc、new等函数从堆中分配到一块内存后,必须调用free或delete进行回收,否则这块内存不能继续被使用。内存泄漏会因为减少可用内存的数量从而降低计算机的性能。最终,在最糟糕的情况下,过多的可用内存被分配掉导致全部或部分设备停止正常工作,或者应用程序崩溃。内存泄漏可能不严重,甚至能够被常规的手段检测出来。在现代操作系统中,一个应用程序使用的常规内存在程序终止时被释放。这表示一个短暂运行的应用程序中的内存泄漏不会导致严重后果。在C++中出现内存泄露的主要原因就是程序猿在申请了内存后(malloc(), new),没有及时释放没用的内存空间,甚至消灭了指针导致该区域内存空间根本无法释放。

内存泄漏的原因

  1. malloc/new和delete/free没有匹配
  2. new[] 和 delete[]也没有匹配
  3. 没有将父类的析构函数定义为虚函数,当父类的指针指向子类对象时,delete该对象不会调用子类的析构函数

检测手段

  1. 良好的程序设计能力,把new和delete全部都封装到构造函数和析构函数中,保证任何资源的释放都在析构函数中进行
  2. 智能指针(万一被问道,这也是一个问题)
  3. valgrind ,这个可以打印出发生内存泄露的部分代码
  4. linux使用swap命令观察还有多少可以用的交换空间,两分钟内执行三四次,肉眼看看交换区是不是变小了
  5. 使用/usr/bin/stat工具如netstat、vmstat等。如果发现波段有内存被分配且没有释放,有可能进程出现了内存泄漏。

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

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

相关文章

视频单目标跟踪研究

由于对视频单目标跟踪并不是很熟悉&#xff0c;所以首先得对该领域有个大致的了解。 视频目标跟踪是计算机视觉领域重要的基础性研究问题之一&#xff0c;是指在视频序列第一帧指定目标 后&#xff0c;在后续帧持续跟踪目标&#xff0c;即利用边界框&#xff08;通常用矩形框表…

printf 命令:格式化输出

一、命令简介 ​printf​ 命令在 Linux 系统中用于格式化并打印字符串到标准输出。它是 C 语言中 printf ​函数的命令行版本&#xff0c;因此其格式化选项与 C 语言中的非常相似。 相关命令&#xff1a; echo&#xff1a;通常使用 echo&#xff0c;它比较简单。printf&…

你们用过微信CRM管理系统吗?

微信CRM管理系统是近年来流行的管理软件&#xff0c;在市场上得到了很高的认可。许多企业正在应用微信CRM管理系统&#xff0c;那系统具体有些什么功能呢&#xff1f; 1、聚合聊天&#xff0c;可以管理多个微信号 2、批量多号自动加好友任务&#xff0c;设置好时间间隔以及加人…

《论软件系统架构风格》写作框架,软考高级系统架构设计师

论文真题 系统架构风格&#xff08;System Architecture Style&#xff09;是描述某一特定应用领域中系统组织方式的惯用模式。架构风格定义了一个词汇表和一组约束&#xff0c;词汇表中包含一些构件和连接件类型&#xff0c;而这组约束指出系统是如何将这些构件和连接件组合起…

李沐对大模型趋势的几点判断,小模型爆发了!

李沐是上海交通大学 2011 届计算机科学与工程系本硕系友。他曾担任亚马逊资深首席科学家&#xff0c;加州大学伯克利分校和斯坦福大学的访问助理教授&#xff0c;是前 Marianas Labs 联合创始人&#xff0c;深度学习框架 Apache MXNet 的创始人之一。目前是 BosonAI 联合创始人…

C++之STL—string容器

本质&#xff1a;类 class 封装了很多方法&#xff1a;查找find&#xff0c;拷贝copy&#xff0c;删除delete 替换replace&#xff0c;插入insert 构造函数 赋值操作 assign&#xff1a; 字符串拼接 &#xff0b; append&#xff1a; string查找和替换 没查找到&#xff0c;po…

【刷题2—滑动窗口】最大连续1的个数lll、将x减到0的最小操作数

目录 一、最大连续1的个数lll二、将x减到0的最小操作数 一、最大连续1的个数lll 题目&#xff1a; 思路&#xff1a; 问题转换为&#xff1a;找到一个最长子数组&#xff0c;这个数组里面0的个数不能超过k个 定义一个变量count&#xff0c;来记录0的个数&#xff0c;进窗口、…

时序预测 | Python实现KAN+LSTM时间序列预测

时序预测 | Python实现KAN+LSTM时间序列预测 目录 时序预测 | Python实现KAN+LSTM时间序列预测预测效果基本介绍程序设计预测效果 基本介绍 时序预测 | KAN+LSTM时间序列预测(Python) KAN作为这两年最新提出的机制,目前很少人用,很适合作为时间序列预测的创新点,可以结合…

【重学 MySQL】三十八、group by的使用

【重学 MySQL】三十八、group by的使用 基本语法示例示例 1: 计算每个部门的员工数示例 2: 计算每个部门的平均工资示例 3: 结合 WHERE 子句 WITH ROLLUP基本用法示例注意事项 注意事项 GROUP BY 是 SQL 中一个非常重要的子句&#xff0c;它通常与聚合函数&#xff08;如 COUNT…

MySQL和SQL的区别简单了解和分析使用以及个人总结

MySQL的基本了解 运行环境&#xff0c;这是一种后台运行的服务&#xff0c;想要使用必须打开后台服务&#xff0c;这个后台服务启动的名字是在安装中定义的如下图&#xff08;个人定义MySQL88&#xff09;区分大小写图片来源 可以使用命令net start/stop 服务名&#xff0c;开…

实验十八:IIC-EEPROM实验

这个实验比较复杂,是目前第一个多文件项目 KEY1-4:P3^0-P3^3 IIC_SCL=P2^1; IIC_SDA=P2^0; //定义数码管位选信号控制脚 LSA=P2^2; LSB=P2^3; LSC=P2^4; 代码 main.c #include "public.h" #in

常见汽车零部件ASIL等级示例

ASIL&#xff08;Automotive Safety Integrity Level&#xff0c;汽车安全完整性等级&#xff09;评级系统是ISO 26262标准中定义的一套风险分类体系&#xff0c;用于评估道路车辆中电子电气系统&#xff08;E/E系统&#xff09;功能安全的风险程度&#xff0c;并确保这些系统在…

Linux相关概念和重要知识点(6)(make、makefile、gdb)

1.make、makefile &#xff08;1&#xff09;什么是make、makefile&#xff1f; 在我们写完代码后&#xff0c;要编译运行&#xff0c;如果有多个.c文件就需要每次都自己用gcc -o来处理&#xff0c;这十分麻烦。当我们想要自定义多个文件的处理时&#xff0c;我们会浪费很多时…

MatrixOne助力一道创新打造高性能智能制造AIOT系统

客户简介 深圳一道创新&#xff08;ETAO Innovation&#xff09;成立于2012年&#xff0c;是一家创新型软件及信息技术服务商&#xff0c;致力于制造戏份行业—电子制造业的数字转型服务&#xff0c;构建万物互联的智能工程。一道创新致力于把先进的软件系统、数字平台、人工智…

拯救者Legion R9000X 2021R(82K8)原厂Win10与Windows11系统恢复镜像下载

LENOVO联想拯救者R9000X锐龙版2021款【82K8】预装OEM系统WIN11/10安装包&#xff0c;恢复原装出厂时开箱状态一模一样 链接&#xff1a;https://pan.baidu.com/s/15dGwacsEG0G8pOiZAHyXaQ?pwd0xgk 提取码&#xff1a;0xgk 联想原装出厂系统自带所有驱动、出厂主题壁纸、系统…

得物App荣获新奖项,科技创新助力高质量发展

近日&#xff0c;备受瞩目的2024中国国际服务贸易交易会&#xff08;简称“服贸会”&#xff09;在北京盛大开幕&#xff0c;这一全球唯一的国家级、国际性、综合型服务贸易盛会再次汇聚了全球服务贸易领域的精英与前沿成果。服贸会由商务部和北京市政府携手打造&#xff0c;并…

大数据系统调优:从DAG到单机

目标&#xff1a;优化T10的时效性全局DAG调度层优化&#xff1a;提前任务开始时间&#xff1a; 1. 优化慢结点&#xff1a;T10依赖了T4,T7,T8, 其中T8为瓶颈&#xff0c;如果T8能提前点完成&#xff0c;T10可以早点开始&#xff0c;就能早点完成 2. 快结点做更多预计算…

Android Studio 真机USB调试运行频繁掉线问题

一、遇到问题 Android Studio使用手机运行项目时&#xff0c;总是频繁掉线&#xff0c;连接很不稳定&#xff0c;动不动就消失&#xff0c;基本上无法使用 二、问题出现原因 1、硬件问题&#xff1a;数据线 换条数据线试试&#xff0c;如果可以&#xff0c;那就是数据线的…

如何登录通义灵码,快速开启AI编码之旅?

通义灵码个人版开发者可以使用阿里云账号登录通义灵码 IDE 端插件&#xff0c;本文介绍个人版开发者登录 IDE 端插件的操作指南。 登录通义灵码 步骤 1&#xff1a;准备工作 已成功注册阿里云账号&#xff0c;具体操作可参考&#xff1a;账号注册&#xff08;PC端&#xff09;…

通信工程学习:什么是SDN软件定义网络

SDN&#xff1a;软件定义网络 SDN&#xff08;Software Defined Network&#xff09;&#xff0c;即软件定义网络&#xff0c;是一种新兴的网络架构和技术&#xff0c;它实现了网络控制平面与数据转发平面的分离&#xff0c;并通过软件平台进行集中控制和管理。以下是SDN的详细…