当前位置: 首页 > news >正文

Effective C++条款14——在资源管理类中小心coping行为(资源管理)

条款13导入这样的观念:“资源取得时机便是初始化时机”(Resource Acquisitionls Initialization; RAII),并以此作为“资源管理类”的脊柱,也描述了auto_ ptr和tr1::shared ptr如何将这个观念表现在 heap-based资源上。然而并非所有资源都是heap-based,对那种资源而言,像auto_ptr和 tr1 : :shared_ptr这样的智能指针往往不适合作为资源掌管者(resource handlers)。既然如此,有可能偶而你会发现,你需要建立自己的资源管理类。

例如,假设我们使用C API函数处理类型为Mutex的互斥器对象( mutexobjects),共有lock和unlock两函数可用:

void lock(Mutex* pm);        // 锁定pm所指的互斥器
void unlock(Mutex* pm);      // 将互斥器解除锁定

为确保绝不会忘记将一个被锁住的 Mutex解锁,你可能会希望建立一个class用来管理机锁。这样的class 的基本结构由RAII守则支配,也就是“资源在构造期间获得,在析构期间释放”:

class Lock {
public:explicit Lock(Mutex* pm):mutexPtr(pm){lock(mutexPtr);            // 获得资源}~Lock() {unlock(mutexPtr);              // 释放资源}private:Mutex* mutexPtr;
};

客户对Lock的用法符合RAII 方式:

Mutex m;        // 定义你所需要的互斥器
// ...
{Lock m1(&m);    // 建立一个区块用来定义关键部分// 锁定互斥器// 执行相关代码
}                   // 自动解除互斥器锁定

这很好,但如果Lock对象被复制,会发生什么事?

Lock m11(&m);            // 锁定m
Lock m12(&m11);          // 将m11复制到m12上,会发生什么

这是某个一般化问题的特定例子。那个一般化问题是每位RAII class作者一定需要面对的:“当一个RAII对象被复制,会发生什么事?”大多数时候你会选择以下两种可能:

  • 禁止复制。许多时候允许RAII对象被复制并不合理。对一个像Lock这样的class这是有可能的,因为很少能够合理拥有“同步化基础器物”( synchronizationprimitives)的复件(副本)。如果复制动作对RAIl class并不合理,你便应该禁止之。条款6告诉你怎么做:将copying操作声明为private。对Lock 而言看起来是这样:
class Lock: private Uncopyable {        // 禁止复制
public:// ...
};
  • ​​​对底层资源祭出“引用计数法”(reference-count)。有时候我们希望保有资源,直到它的最后一个使用者(某对象)被销毁。这种情况下复制RAII对象时,应该将资源的“被引用数”递增。tr1 : :shared_ ptr便是如此。

通常只要内含一个tr1::shared _ptr成员变量,RAII classes 便可实现出reference-counting copying行为。如果前述的 Lock打算使用reference counting,它可以改变mutexPtr的类型,将它从Mutex*改为tr1::shared_ ptr<Mutex>。然而很不幸tr1::shared ptr的缺省行为是“当引用次数为О时删除其所指物”,那不是我们所要的行为。当我们用上一个Mutex,我们想要做的释放动作是解除锁定而非删除。

幸运的是 tr1::shared_ptr 允许指定所谓的“删除器”(deleter),那是一个函数或函数对象(function object),当引用次数为0时便被调用(此机能并不存在于auto_ptr——它总是将其指针删除)。删除器对tr1::shared _ptr构造函数而言是可有可无的第二参数,所以代码看起来像这样:

class Lock {
public:explicit Lock(Mutex* pm):mutexPtr(pm, unlock){lock(mutexPtr.get());}private:std::tr1::shared_ptr<Mutex> mutexPtr;        // 使用shared_ptr代替
};

请注意,本例的Lock class不再声明析构函数。因为没有必要。条款5说过,class析构函数(无论是编译器生成的,或用户自定的)会自动调用其non-static成员变量(本例为mutexPtr)的析构函数。而
mutexPtr的析构函数会在互斥器的引用次数为0时自动调用tr1::shared_ptr的删除器(本例为unlock)。(当你阅读这个class的原始码,或许会感谢其中有条注释指出:你并没有忘记析构,你只是倚赖了编译器生成的缺省行为。)

  • 复制底部资源。有时候,只要你喜欢,可以针对一份资源拥有其任意数量的复件(副本)。而你需要“资源管理类”的唯一理由是,当你不再需要某个复件时确保它被释放。在此情况下复制资源管理对象,应该同时也复制其所包覆的资源。也就是说,复制资源管理对象时,进行的是“深度拷贝”。
    某些标准字符串类型是由“指向heap内存”之指针构成(那内存被用来存放字符串的组成字符)。这种字符串对象内含一个指针指向一块heap内存。当这样一个字符串对象被复制,不论指针或其所指内存都会被制作出一个复件。这样的字符串展现深度复制(deep copying)行为。
  • 转移底部资源的拥有权。某些罕见场合下你可能希望确保永远只有一个RAI对象指向一个未加工资源(raw resource),即使RAII对象被复制依然如此。此时资源的拥有权会从被复制物转移到目标物。一如条款13所述,这是auto_ptr奉行的复制意义。

Coping函数(包括copy构造函数和copy assignment操作符)有可能被编译器自动创建出来,因此除非编译器所生版本做了你想要做的事(条款5提过其缺省行为),否则你得自己编写它们。某些情况下你或许也想支持这些函数的一般版本,这样的版本描述于条款45。

请记住

  • 复制RAII 对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为。
  • 普遍而常见的 RAII class copying行为是:抑制copying、施行引用计数法(reference counting)。不过其他行为也都可能被实现。

相关文章:

Effective C++条款14——在资源管理类中小心coping行为(资源管理)

条款13导入这样的观念:“资源取得时机便是初始化时机”(Resource Acquisitionls Initialization; RAII)&#xff0c;并以此作为“资源管理类”的脊柱&#xff0c;也描述了auto_ ptr和tr1::shared ptr如何将这个观念表现在 heap-based资源上。然而并非所有资源都是heap-based&am…...

【网络教程】如何创建/添加钉钉机器人以及如何获取机器人的Token/Secret

文章目录 创建钉钉机器人添加钉钉机器人获取机器人的Token/Secret相关网站创建钉钉机器人 这里以PC端的操作为例,按照如下操作进行 访问 钉钉开放平台选择机器人选项卡,点击右上角的创建应用,这里会有一个弹窗,我这里选择的是继续使用旧版,如图按照要求填写相关信息创建自…...

wx原生微信小程序入门常用总结

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、定义值和修改值1、定义值2、修改值&#xff08;1&#xff09;代码&#xff08;2&#xff09;代码说明&#xff08;3&#xff09;注意点 二、点击事件三、微…...

制作一个专属于安防监控业的小程序商城

随着科技的发展和人们生活水平的提高&#xff0c;安防监控设备在我们的日常生活中起到了越来越重要的作用。因此&#xff0c;建立一个安防监控设备商城小程序就变得尤为重要。下面将介绍如何建立这样一个小程序。 第一步&#xff0c;登录乔拓云平台后台&#xff0c;进入商城管理…...

基于java羽毛球馆管理系统设计与实现

摘 要 时代的变化速度实在超出人类的所料&#xff0c;21世纪&#xff0c;计算机已经发展到各行各业&#xff0c;各个地区&#xff0c;它的载体媒介-计算机&#xff0c;大众称之为的电脑&#xff0c;是一种特高速的科学仪器&#xff0c;比人类的脑袋要灵光无数倍&#xff0c;什么…...

安装elasticsearch8.9.0及修改配置

安装es流程 打开文件,添加以下行 vim /etc/sysctl.conf vm.max_map_count=262144重启生效 sysctl -p创建用户 useradd es passwd es修改es目录所属用户 chown -R es:es /opt/elasticsearch-8.9.0如果内存不足,可以修改es的初始化内存和Max内存,修改文件/opt/elasticsearch-8…...

如何构建高效的接口自动化测试框架?看完你就会了...

在选择接口测试自动化框架时&#xff0c;需要根据团队的技术栈和项目需求来综合考虑。对于测试团队来说&#xff0c;使用Python相关的测试框架更为便捷。无论选择哪种框架&#xff0c;重要的是确保 框架功能完备&#xff0c;易于维护和扩展&#xff0c;提高测试效率和准确性。今…...

53 | 金融行业股票销售指标分析

金融行业股票销售指标分析 引言: 金融行业中的股票销售指标分析是评估股票市场表现、投资者行为以及交易平台效果的重要手段。通过深入分析关键的销售指标,投资者、金融机构和交易平台可以更好地了解市场趋势,作出明智的投资决策,优化交易策略。本文将探讨金融行业股票销售…...

qiuzhiji1

前言:记录一下毕业后的求职历程 背景:18级 湖北理工学院计算机学院(黄石) 网络工程 本文初次撰写于2023年8月17日,正处于离职找工作的空档期,部分经历可能记不清了。所有内容尽量保证了客观,主要是分享一下自己的经历,顺带锻炼文字能力。 文章会不定期更新,较新的日期会…...

使用VisualStudio制作上位机(二)

文章目录 使用VisualStudio制作上位机(二)第三部分:GUI内部函数设计使用VisualStudio制作上位机(二) Author:YAL 第三部分:GUI内部函数设计 事件添加 给窗体或窗体按钮相关的操作添加事件有两种方式,事件的名字直白的表面了这是什么事件。 直接双击界面,自动生成窗…...

Datawhale AI夏令营 - 用户新增预测挑战赛 | 学习笔记

数据分析与可视化 为了拟合出更好的结果就要了解训练数据之间的相互关系&#xff0c;进行数据分析是必不可少的一步 导入必要的库 # 导入库 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns pandas库是一个强大的分析结构化…...

HarmonyOS/OpenHarmony(Stage模型)卡片开发AbilityStage组件容器

AbilityStage是一个Module级别的组件容器&#xff0c;应用的HAP在首次加载时会创建一个AbilityStage实例&#xff0c;可以对该Module进行初始化等操作。 AbilityStage与Module一一对应&#xff0c;即一个Module拥有一个AbilityStage。 DevEco Studio默认工程中未自动生成Abilit…...

利用torchvision库实现目标检测与语义分割

一、介绍 利用torchvision库实现目标检测与语义分割。 二、代码 1、目标检测 from PIL import Image import matplotlib.pyplot as plt import torchvision.transforms as T import torchvision import numpy as np import cv2 import randomCOCO_INSTANCE_CATEGORY_NAMES …...

基于决策树(Decision Tree)的乳腺癌诊断

决策树(DecisionTree)学习是以实例为基础的归纳学习算法。算法从--组无序、无规则的事例中推理出决策树表示形式的分类规则,决策树也能表示为多个If-Then规则。一般在决策树中采用“自顶向下、分而治之”的递归方式,将搜索空间分为若千个互不相交的子集,在决策树的内部节点(非叶…...

前端面试的计算机网络部分(2)每天10个小知识点

目录 系列文章目录前端面试的计算机网络部分&#xff08;1&#xff09;每天10个小知识点 知识点11. DNS 完整的查询过程递归查询过程&#xff1a;迭代查询过程&#xff1a; 12. OSI 七层模型13. TCP 的三次握手和四次挥手三次握手&#xff08;Three-Way Handshake&#xff09;&…...

【LeetCode】224. 基本计算器

224. 基本计算器&#xff08;困难&#xff09; 方法&#xff1a;双栈解法 思路 我们可以使用两个栈 nums 和 ops 。 nums &#xff1a; 存放所有的数字ops &#xff1a;存放所有的数字以外的操作&#xff0c;/- 也看做是一种操作 然后从前往后做&#xff0c;对遍历到的字符做…...

服务器数据恢复-EVA存储磁盘故障导致存储崩溃的数据恢复案例

EVA系列存储是一款以虚拟化存储为实现目的的中高端存储设备。EVA存储中的数据在EVA存储设备工作过程中会不断进行迁移&#xff0c;如果运行的任务比较复杂&#xff0c;EVA存储磁盘负载加重&#xff0c;很容易出现故障的。EVA存储通过大量磁盘的冗余空间和故障后rss冗余磁盘动态…...

【stylus】通过css简化搜索页面样式

发现stylus专门修改样式的插件后&#xff0c;发现之前写JS调整样式的方式是在太蠢了&#xff0c;不过有一些交互的东西还是得用JS&#xff0c;例如设置按钮来交互显示功能&#xff0c;或记录功能等。插件可以让简化网站变得简单&#xff0c;而且可以实时显示&#xff0c;真的不…...

【官方中文文档】Mybatis-Spring #使用 SqlSession

使用 SqlSession 在 MyBatis 中&#xff0c;你可以使用 SqlSessionFactory 来创建 SqlSession。 一旦你获得一个 session 之后&#xff0c;你可以使用它来执行映射了的语句&#xff0c;提交或回滚连接&#xff0c;最后&#xff0c;当不再需要它的时候&#xff0c;你可以关闭 s…...

Redis三种持久化方式详解

一、Redis持久性 Redis如何将数据写入磁盘 持久性是指将数据写入持久存储&#xff0c;如固态磁盘&#xff08;SSD&#xff09;。Redis提供了一系列持久性选项。其中包括&#xff1a; RDB&#xff08;快照&#xff09;&#xff1a;RDB持久性以指定的时间间隔执行数据集的时间点…...

计算机毕业设计springboot众筹系统 基于SpringBoot的校园项目众筹融资平台设计与实现 高校创新创业众筹服务与资金管理系统构建研究

计算机毕业设计springboot众筹系统&#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。 随着我国经济的高速发展与人们生活水平的日益提高&#xff0c;人们对生活质量的追求也多种多样…...

XCZU67DR的PS和PL怎么协同干活?一个案例讲透ARM核与FPGA联动处理高速ADC数据流

XCZU67DR异构计算实战&#xff1a;ARM核与FPGA协同处理5.9G ADC数据流的架构设计 在当今信号处理领域&#xff0c;实时处理高速ADC数据流已成为雷达、通信和医疗成像等应用的核心需求。当采样率攀升至5.9G级别时&#xff0c;传统CPU或FPGA单独处理的架构往往捉襟见肘。这正是Xi…...

Qwen2.5-VL-7B-Instruct实操手册:对话历史自动保存+一键清空功能详解

Qwen2.5-VL-7B-Instruct实操手册&#xff1a;对话历史自动保存一键清空功能详解 1. 开篇&#xff1a;你的全能视觉助手来了 今天给大家介绍一个特别实用的工具——基于Qwen2.5-VL-7B-Instruct多模态大模型的视觉交互工具。这个工具专门为RTX 4090显卡优化过&#xff0c;用上了…...

如何用SVGnest提升材料利用率:从问题到解决方案的完整指南

如何用SVGnest提升材料利用率&#xff1a;从问题到解决方案的完整指南 【免费下载链接】SVGnest An open source vector nesting tool 项目地址: https://gitcode.com/gh_mirrors/sv/SVGnest 制造业材料浪费的隐形成本&#xff1a;您的企业是否正在损失30%利润&#xff…...

Go语言广播系统设计:基于Channel的高性能事件分发机制

引言 在后端系统架构中&#xff0c;事件广播是一种常见的通信模式。本文将深入分析一个基于Go语言channel实现的广播管理器&#xff0c;探讨其设计思想、实现细节以及在实际项目中的应用价值。 参考代码 点击直达 背景与需求 在许多应用场景中&#xff0c;我们需要实现一对…...

ABC系统实战指南:革新数字电路设计的逻辑综合与形式验证技术突破

ABC系统实战指南&#xff1a;革新数字电路设计的逻辑综合与形式验证技术突破 【免费下载链接】abc ABC: System for Sequential Logic Synthesis and Formal Verification 项目地址: https://gitcode.com/gh_mirrors/ab/abc 在现代集成电路设计流程中&#xff0c;工程师…...

S7-200 PLC与组态王称重配料生产线自动控制系统:后继产品包含梯形图、接线图、原理图及I...

S7-200 PLC和组态王称重配料生产线自动控制系统配料 我们主要的后发送的产品有&#xff0c;带解释的梯形图接线图原理图图纸&#xff0c;io分配&#xff0c;组态画面上周刚结了个小单子&#xff0c;给本地一家饲料厂改了套半自动的称重配料线&#xff0c;用的就是S7-200 PLC加…...

PyTorch 2.8镜像多场景落地:在线教育平台个性化习题生成引擎部署

PyTorch 2.8镜像多场景落地&#xff1a;在线教育平台个性化习题生成引擎部署 1. 教育行业的AI转型机遇 在线教育行业正面临个性化学习的迫切需求。传统题库系统存在内容同质化、更新成本高、难以匹配学生个体差异等问题。基于PyTorch 2.8构建的个性化习题生成引擎&#xff0c…...

企业生产环境怎么正确做 Vibe Coding:不是让 AI 接管,而是把交付流程做成可控系统

这两年&#xff0c;vibe coding 很热。很多团队第一次接触它时&#xff0c;直觉都是&#xff1a;既然 AI 会写代码&#xff0c;那就让它多写一点&#xff0c;人少管一点&#xff0c;速度自然就上来了。 但一进企业生产环境&#xff0c;这种想法通常很快撞墙。 因为企业真正关心…...

终极指南:如何在Open Interpreter中快速集成vLLM高速推理引擎

终极指南&#xff1a;如何在Open Interpreter中快速集成vLLM高速推理引擎 【免费下载链接】open-interpreter Open Interpreter 工具能够让大型语言模型在本地执行如Python、JavaScript、Shell等多种编程语言的代码。 项目地址: https://gitcode.com/GitHub_Trending/op/open…...