突破编程_C++_面试(基础知识(6))

面试题14:什么是 RAII 编程方法

RAII(Resource Acquisition Is Initialization)是C++的发明者 Bjarne Stroustrup 提出的概念,也称为资源获取就是初始化,是一种管理资源、避免泄漏的编程方法。 它的基本思想是在对象的构造函数中获取资源,并在对象的析构函数中释放资源。通过这种方式,资源管理被封装在对象的生命周期中,从而简化了资源的获取和释放,避免了手动管理资源时可能出现的错误。
RAII 的核心思想是将资源的生命周期与对象的生命周期绑定在一起。当对象被创建时,它会自动获取所需的资源;当对象被销毁时,它会自动释放所拥有的资源。这种方式可以确保资源的正确获取和释放,避免了资源泄漏和内存泄漏等问题。
比如针对上面章节中在释放内存前有返回操作的场景,使用 RAII 编程方法可以作如下代码调整:

#include <iostream>class SmartVal
{
public:SmartVal(){printf("automatically apply for memory\n");m_val = new int;}~SmartVal(){if (nullptr != m_val){printf("automatically release for memory\n");delete m_val;m_val = nullptr;}}public:int* getVal(){return m_val;}private:int* m_val = nullptr;
};void doSomething(int type)
{SmartVal val;if (0 != type){return;			//OK:val 申请的内存会自动释放}
}int main()
{doSomething(0);return 0;
}

上面代码的输出为:

automatically apply for memory
automatically release for memory

通过在构造函数自动申请内存,在析构函数中自动释放内存,从而避免了由于忘记正确释放内存导致内存泄漏。除了对于内存的自动管理,RAII 还可以应用于其他类型的资源管理,如文件句柄、网络连接等。通过将资源的获取和释放封装在相应的对象中,可以简化资源的管理,提高代码的可读性和可维护性。根据 RAII 编程方法, C++11 标准引入了能够自动管理动态内存的智能指针。

面试题15:如何解决智能指针的循环依赖问题

使用 weak_ptr 解决循环引用问题。循环引用是指两个或更多智能指针相互引用,形成一个闭环,导致它们的引用计数永远不会降到0,从而使得它们管理的内存无法得到释放。
使用 weak_ptr 可以打破这个循环,因为它不增加所指向对象的引用计数。当一个 shared_ptr 和一个 weak_ptr 相互引用时,只有当 shared_ptr 的引用计数变为 0 时,对象才会被销毁。而 weak_ptr 可以通过调用 lock() 方法来尝试获取一个临时的 shared_ptr,以安全地访问对象。如果对象已经被销毁,lock() 方法将返回一个空的 shared_ptr。如下为样例代码:

#include <iostream>  
#include <memory>  using namespace std;class A;
class B;class A
{
public:A() {}~A() {printf("destroy A\n");}public:void setB(shared_ptr<B> b){m_b = b;}private:shared_ptr<B> m_b;
};class B
{
public:B() {}~B(){printf("destroy B\n");}public:void setA(shared_ptr<A> a){m_a = a;}private:weak_ptr<A> m_a;
};int main() {shared_ptr<A> a(new A);shared_ptr<B> b(new B);a->setB(b);b->setA(a);return 0;
}

上面代码的输出为:

destroy A
destroy B

面试题16:unique_ptr 如何实现独占所有权

unique_ptr 在其生命周期内拥有它所指向的对象的唯一所有权,其他任何指针(包括其他 unique_ptr )都不能同时拥有该对象的所有权。当 unique_ptr 被销毁时(例如离开其作用域或被重新赋值),它所拥有的对象也会被自动删除。
unique_ptr 实现独占所有权的技术原理主要有以下 4 点:
(1)内部私有指针:unique_ptr 内部维护一个私有的原始指针,该指针指向它所拥有的对象。外部代码不能直接访问它。
(2)排他性:unique_ptr 不支持复制语义,从而可以保证了在任何时候都只有一个 unique_ptr 拥有指向对象的所有权。
(3)移动语义:unique_ptr 支持移动语义,允许将一个 unique_ptr 的所有权移动给另一个 unique_ptr ,但不能复制它。这是通过将 unique_ptr 的拷贝构造函数和拷贝赋值运算符设置为 delete (即禁用),同时提供移动构造函数和移动赋值运算符来实现的。
(4)资源释放:unique_ptr 通过RAII(资源获取即初始化)原则来实现在其生命周期结束时自动释放其拥有的资源(如动态分配的内存):在构造函数中获取资源,在析构函数中释放(析构函数中可以调用自定义删除器)。
样例代码如下:

unique_ptr<int> ptr1(new int); // 创建unique_ptr并初始化 
unique_ptr<int> ptr2 = ptr1; 	// 错误:不能复制 unique_ptr  
unique_ptr<int> ptr3 = move(ptr1); // 正确: 移动 unique_ptr 的所有权 

面试题17:shared_ptr 如何实现内部的引用计数机制

shared_ptr 的内部引用计数机制通常是通过内部使用一个控制块(control block)来实现的。当创建一个 shared_ptr 时,它会在堆上分配一个控制块,并将引用计数初始化为 1。然后,shared_ptr 内部的指针实际上是指向这个控制块的指针,而不是直接指向所管理的对象。控制块内部有一个指针指向实际的对象。
以下是 shared_ptr 实现引用计数的一些关键步骤:
(1)构造函数:当创建一个新的 shared_ptr 并指向某个对象时,如果这是第一个 shared_ptr 指向该对象,它会分配一个新的控制块,并将引用计数设置为 1。然后,shared_ptr 的内部指针指向这个控制块。如果已经有其他的 shared_ptr 指向该对象,它会增加现有控制块的引用计数。
(2)拷贝构造函数和拷贝赋值:当使用拷贝构造函数或拷贝赋值运算符创建一个新的 shared_ptr 时,它会增加现有控制块的引用计数,并使新的 shared_ptr 指向同一个控制块。
(3)移动构造函数和移动赋值:与 unique_ptr 类似,shared_ptr 也支持移动语义。当使用移动构造函数或移动赋值运算符时,它会将所有权从一个 shared_ptr 移动到另一个 shared_ptr,而不改变引用计数。
(4)析构函数:当 shared_ptr 的析构函数被调用时(例如,shared_ptr 离开其作用域),它会减少控制块的引用计数。如果引用计数变为 0,这表明没有其他 shared_ptr 再指向该对象,因此 shared_ptr 会删除控制块和所管理的对象,并释放内存。
(5)自定义删除器:shared_ptr 允许用户提供自定义的删除器,用于在删除对象时执行特定的操作。例如,可以使用自定义删除器来调用对象的自定义析构函数,或者执行其他清理任务。

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

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

相关文章

Hadoop-生产调优

第1章 HDFS-核心参数 1.1 NameNode内存生产配置 1&#xff09;NameNode 内存计算 每个文件块大概占用 150 byte&#xff0c;一台服务器 128G 内存为例&#xff0c;能存储多少文件块呢&#xff1f; 128 * 1024 * 1024 * 1024 / 150byte ≈ 9.1 亿G MB KB Byte 2&#xff09…

Leetcode 279 完全平方数

题意理解&#xff1a; 给你一个整数 n &#xff0c;返回 和为 n 的完全平方数的最少数量 。 完全平方数 是一个整数&#xff0c;其值等于另一个整数的平方&#xff1b;换句话说&#xff0c;其值等于一个整数自乘的积。例如&#xff0c;1、4、9 和 16 都是完全平方数&#xff0c…

FPGA_工程_按键控制的基于Rom数码管显示

一 信号 框图&#xff1a; 其中 key_filter seg_595_dynamic均为已有模块&#xff0c;直接例化即可使用&#xff0c;rom_8*256模块&#xff0c;调用rom ip实现。Rom_ctrl模块需要重新编写。 波形图&#xff1a; 二 代码 module key_fliter #(parameter CNT_MAX 24d9_999_99…

AT_abl_d 题解

线段树优化 DP 的板子。 题意 给定一个数列&#xff0c;求出它最长的子序列&#xff0c;满足相邻元素之差不大于 k k k。 分析 对于这类最长子序列的题目&#xff0c;有一个 DP 套路&#xff0c;设 d p i dp_i dpi​ 表示以 a i a_i ai​ 结尾的最长合法子序列长度&…

Filter 实现过滤符合条件的请求并落库

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、配置过滤器类 二、定义数据表、实体类、Mapper 2.1 DDL 2.2 实体类 2.3 Mapper 三、创建一个过滤器 四、实现 Nacos 配置…

通用的网站炫酷底部美化代码分享

网站炫酷底部美化代码介绍 这段代码采用了最新的前端技术&#xff0c;确保在各种浏览器和设备上都能完美展现。它包含响应式设计元素&#xff0c;这意味着无论用户是通过电脑、平板还是手机访问您的网站&#xff0c;底部都能呈现出最佳的效果。 此外&#xff0c;我们还特别注…

怎么做?这么做。

一、每天输入 每天读2——3篇文章&#xff0c;可以是行业趋势、技术推文(与自己的工作有关的方向)&#xff0c; 每天坚持一年就会是 1000 篇。 推荐&#xff1a; 大厂的技术博客&#xff1a;纯技术类&#xff0c;美团技术团队、阿里技术团队&#xff1b; 科技资讯类&#xff1…

电子电器架构 —— 网关测试脚本分析

电子电器架构 —— 网关测试 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何 消耗你的人和事,多看一眼都是你的不对。非…

海外云手机的核心优势

随着5G时代的到来&#xff0c;云计算产业正处于高速发展的时期&#xff0c;为海外云手机的问世创造了一个可信任的背景。在资源有限且需求不断增加的时代&#xff0c;将硬件设备集中在云端&#xff0c;降低个人用户的硬件消耗&#xff0c;同时提升性能&#xff0c;这一点单单就…

微软.NET6开发的C#特性——类、结构体和联合体

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;看到不少初学者在学习编程语言的过程中如此的痛苦&#xff0c;我决定做点什么&#xff0c;下面我就重点讲讲微软.NET6开发人员需要知道的C#特性。 C#经历了多年发展&#xff0c; 进行了多次重大创新&#xf…

[嵌入式系统-8]:软件(Software)、代码(Code)、程序(Program)三者的区别

概述 在工作中&#xff0c;软件、代码、程序这三个词经常被换用&#xff0c;大部分情况下&#xff0c;这种混用都不会出问题&#xff0c;实际上&#xff0c;它们是不同的概念&#xff0c;有相交的部分&#xff0c;也有不同的地方。本文就简单阐述一下他们的区别。 在计算机领…

c++基本介绍

C是一种高级的编程语言&#xff0c;广泛应用于软件开发和系统编程。它是C语言的扩展&#xff0c;提供了更多的特性和功能。 以下是一个简单的C教程&#xff0c;可以帮助你入门&#xff1a; 安装C编译器&#xff1a; 首先&#xff0c;你需要安装一个C编译器&#xff0c;例如GCC…

14 归并排序和其他排序

1.归并排序 2.计数排序 1. 归并排序 基本思想 建立在归并操作上的一种排序算法,采用分治法的一个典型应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff0c;将两个有序表合成一个称为二路归并。 原数组无序&#xff0c;以中间分割为两个数组&#xff0c;…

vue 实现 手机号中间4位分格输入框(暂无选中标识

vue 实现 手机号中间4位分格输入框 效果图 <!--4位分格输入框--> <!--<template><div><div style"display: flex;"><div class"phone-input"><inputv-for"(digit, index) in digits":key"index"…

SQL--多表查询

我们之前在讲解SQL语句的时候&#xff0c;讲解了DQL语句&#xff0c;也就是数据查询语句&#xff0c;但是之前讲解的查询都是单 表查询&#xff0c;而本章节我们要学习的则是多表查询操作&#xff0c;主要从以下几个方面进行讲解。 多表关系 项目开发中&#xff0c;在进行数据…

SpringMVC原理(设计原理+启动原理+工作原理)

文章目录 前言正文一、设计原理1.1 servlet生命周期简述1.2 设计原理小结 二、启动原理2.1 AbstractHandlerMethodMapping 初始化 --RequestMapping注解解析2.2 DispatcherServlet 的初始化2.3 DispatcherServlet#initHandlerMappings(...) 初始化示例说明 三、工作原理 前言 …

【Rust】——Hello_cargo

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

C语言:矩阵中的最小元素

题目描述 给定一个5X5的整数矩阵&#xff0c;找出其中最小的元素&#xff0c;输出所在的行号、列号和元素值&#xff0c;其中行号和列号都从0开始。 例如&#xff0c;有矩阵&#xff1a; 5 86 53 50 18 25 67 79 44 68 79 63 24 84 100 42 30 59 47 37 28 10 32 23 81 其中最小…

Go基础学习笔记-知识点

学习笔记记录了我在学习官方文档过程中记的要点&#xff0c;可以参考学习。 go build *.go 文件 编译 go run *.go 执行 go mod init 生成依赖管理文件 gofmt -w *.go 格式换名称的大小写用来控制方法的可见域主方法及包命名规范 package main //注意package的命名&#xff0…

ARM PAC指针认证的侧信道攻击——PACMAN安全漏洞

目录 Q1. PACMAN论文的内容是什么? Q2. Arm处理器是否存在漏洞? Q3. 受Arm合作伙伴架构许可设计的处理器实现是否受到影响? Q4. Cortex-M85受到影响吗?