effective c++ 笔记 条款13-18

条款13 以对象管理资源

对象的delete,可能因为前文的一些语句抛出异常或者过早的return(可能是最初的设计也可能多个迭代版本之后的维护导致)使得delete并没有执行,导致内存泄漏。
因此以对象管理资源。并采用RAII(Resource Acquisition Is Initialize,资源取得时机便是初始化时机,即获得资源后立刻放进管理对象),让管理对象的析构函数负责资源的释放。当对象被销毁时自动释放获取的堆资源。
C++11 中,使用std::unique_ptr管理RAII唯一所有权对象,使用std::shared_ptr引用计数来管理RAII对象

std::unique_ptr<Investment> pUniqueInv1(CreateInvestment());
std::unique_ptr<Investment> pUniqueInv2(std::move(pUniqueInv1));    // 转移资源所有权
std::shared_ptr<Investment> pSharedInv1(CreateInvestment());
std::shared_ptr<Investment> pSharedInv2(pSharedInv1);	//引用计数+1

条款14 在资源管理类小心copying行为

复制一个RAII对象时:所有资源的copying行为决定RAII对象的copying行为。
几种常见的copying行为:
1.禁止复制:多数时候RAII对象不允许被复制,需要明确禁止复制行为,条款6
2.对底层资源进行“引用计数法”:类似shared_ptr,每次复制对象计数+1,每个对象离开定义域调用析构使计数-1.为0时销毁资源
3.复制底层资源:制对象的同时复制底层资源即深拷贝。不仅复制指针,也复制指针所指数据
4.转移底层资源所有权:类似unique_ptr,只有一个对象拥有对资源的管理权,复制对象时转移管理权

条款15 在资源管理类中提供对原始资源的访问

STL 中的智能指针提供了对原始资源的隐式访问和显式访问

Investment* p = pSharedInv.get();    // 显式访问原始资源
(*pSharedInv).func();           // 隐式访问原始资源
pSharedInv->func();				// 隐式访问原始资源

设计自己的资源管理类时,也要考虑在提供对原始资源的访问,使用显式访问还是隐式访问的方法,还是两者皆可。

class Font{
public:FontHandle Get() const { return f; }       // 显式转换函数operator FontHandle() const { return f; }  // 隐式转换函数
private:FontHandle f;
}

一般而言显示转换安全,隐式转换对客户端较方便

FontHandle f2 = f1;		//原意是拷贝一个Font对象,却将f1隐式转换为底部的FontHandle,然后才复制

条款16 成对使用 new 和 delete 时要采用相同形式

使用new来分配单一对象,使用new[]来分配对象数组,必须明确它们的行为并不一致,分配对象数组时会额外在内存中记录“数组大小”,而使用delete[]会根据记录的数组大小多次调用析构函数,使用delete则仅仅只会调用一次析构函数

int* arr = new int[10];
int* obj = new int;
delete[] arr;
delete obj;

typedef定义数组类型会带来额外的风险

typedef std::string AddressLines[4];
std::string* pal = new AddressLines;    // pal 是一个对象数组,而非单一对象
delete pal;                             // 行为未定义
delete[] pal;                           // 正确

一般没必要对数组进行 typedefs,因为C++标准库中的 vector,string 等 templates,足以代替数组

条款17:以独立语句将newed对象置入智能指针

int priority();
void processWidget(std::shared_ptr<Widget> pw, int priority);
processWidget(std::shared_ptr<Widget>(new Widget()), priority());

上述调用可能造成内存泄漏.
在调用processWidget函数之前编译器会做以下三件事情:
执行new Widget()表达式动态创建Widget对象。
调用shared_ptr类的构造函数并使用Widget对象的指针作为构造参数。
调用priority函数生成优先级。
new Widget肯定在shared_ptr前,但priority可能在1,2,3任一步骤。若在步骤2执行,并发生了异常,则new Widget()返回的指针将丢失。因为在【资源被创建】和【资源被管理对象接管】之间造成了异常干扰。
解决办法:

std::shared_ptr<Widget> pw(new Widget());
processWidget(pw, priority());

编译器对跨越语句的各项操作没有重排列自由。
新的c++做法

auto pUniqueInv = std::make_unique<Investment>();    // since C++14
auto pSharedInv = std::make_shared<Investment>();    // since C++11
processWidget(std::make_shared<Widget>(), priority());

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

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

相关文章

Rust基础拾遗--进阶

Rust基础拾遗 前言1.结构体2.枚举与模式3.运算符重载4.迭代器5.集合 前言 通过Rust程序设计-第二版笔记的形式对Rust相关重点知识进行汇总&#xff0c;读者通读此系列文章就可以轻松的把该语言基础捡起来。 1.结构体 2.枚举与模式 3.运算符重载 4.迭代器 5.集合

Shell - 学习笔记 - 2.10 - Shell字符串截取

Shell 截取字符串通常有两种方式&#xff1a;从指定位置开始截取和从指定字符&#xff08;子字符串&#xff09;开始截取。 从指定位置开始截取 这种方式需要两个参数&#xff1a;除了指定起始位置&#xff0c;还需要截取长度&#xff0c;才能最终确定要截取的字符串。 既然需要…

CSS基础---新手入门级详解

CSS:层叠样式表 CSS&#xff08;Cascading Style Sheets,层叠样式表&#xff09;&#xff0c;是一种用来为结构化文档添加样式&#xff08;字体、间距和颜色&#xff09;的计算机语言&#xff0c;css扩展名为.css。 实例: <!DOCTYPE html><html> <head><…

OpenAI---提示词工程的6大原则

OpenAI在官方的文档里上线了Prompt engineering&#xff0c;也就是提示词工程指南&#xff0c;其中OpenAI有提到写提示词的6条大的原则&#xff0c;它们分别是&#xff1a; &#xff08;1&#xff09;Write clear instructions&#xff08;写出清晰的指令&#xff09; &#xf…

STM32CubeMX,定时器之定时功能,入门学习,如何设置prescaler,以及timer计算PWM输入捕获方法(重要)

频率变小&#xff0c;周期变长 1&#xff0c;参考链接&#xff08;重要&#xff09; STM32CubeMX——定时器之定时功能&#xff08;学习使用timer定时器的设置&#xff09; STM32测量PWM信息&#xff08;学习使用设置pwm输入捕获&#xff09; 通用定时器中两个重要参数的设置心…

Pytorch+NCCL源码编译

目录 环境1. 安装cudnn2. 使用pytorch自带NCCL库进行编译3. 修改NCCL源代码并重新编译后测试&#xff0c;体现出源码更改 环境 Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-91-generic x86_64)cuda 11.8 cudnn 8python 3.10torch V2.0.1 nccl 2.14.3NVIDIA GeForce RTX 4090 *2 1.…

快速搭建 nfs 环境, 解决 nfs 搭建时的疑难杂症

博客原文 nfs 环境搭建 简介: NFS&#xff08;Network File System&#xff09;即网络文件系统&#xff0c;是FreeBSD支持的文件系统中的一种&#xff0c;它允许网络中的计算机之间共享资源。 在NFS的应用中&#xff0c;本地NFS的客户端应用可以透明地读写位于远端NFS服务器上…

[ai笔记2] 团年饭ai制图大比拼

欢迎来到文思源想的ai空间&#xff0c;这是技术老兵重学ai以及成长思考的第2篇分享&#xff01; 今天我们用国内七个大厂的ai制图工具做一下团年饭图片&#xff01; 1 团年饭ai制图大比拼 昨天期待了许久的ai春晚&#xff0c;并没有如期举行&#xff0c;换成了初一晚上&…

Vue源码系列讲解——模板编译篇【一】(综述)

目录 1. 前言 2. 什么是模板编译 3. 整体渲染流程 4. 模板编译内部流程 4.1 抽象语法树AST 4.2 具体流程 5. 总结 1. 前言 在前几篇文章中&#xff0c;我们介绍了Vue中的虚拟DOM以及虚拟DOM的patch(DOM-Diff)过程&#xff0c;而虚拟DOM存在的必要条件是得先有VNode&…

随机MM引流源码PHP开源版

引流源码最新随机MM开源版PHP源码&#xff0c;非常简洁好看的单页全解代码没任何加密 直接上传即可用无需数据库支持主机空间

vue3初识

目录 一、前言二、主观感受三、vue3初探 原文以及该系列教程文章后续可点击这里查看&#xff1a;vue初识 一、前言 Vue.js是一款流行的前端框架&#xff0c;最初由尤雨溪&#xff08;Evan You&#xff09;于2014年创建&#xff0c;非常的年轻。官网为vue3&#xff0c; 但要注…

OpenCV基础

OpenCV简介 OpenCV是一个功能强大的开源计算机视觉和机器学习软件库&#xff0c;它在图像处理和视频分析领域得到了广泛应用。OpenCV最初由英特尔公司于1999年发起并支持&#xff0c;后来由Willow Garage和Itseez&#xff08;现在是Intel的一部分&#xff09;维护。它是为了推…

题目练习(生死时速2.0版)

题目一&#xff08;Before an Exam&#xff09; 题意翻译 题目背景 明天皮特将要考生物。他并不很喜欢生物&#xff0c;但在 d 天前他得知他将不得不参加此次考试。皮特严厉的父母勒令他立即复习&#xff0c;因此他在第 i 天将需要学习不少于 minTimei​ 小时&#xff0c;不…

鸿蒙harmony--TypeScript函数详解

新的一年开始了&#xff0c;每天给自己一个微笑&#xff0c;笑里有幸福&#xff0c;原谅生活中的不完美&#xff0c;宽容生活中的不容易&#xff0c;删除昨天的烦恼&#xff0c;开启今天的快乐&#xff01; 目录 一&#xff0c;函数类型表达式 二&#xff0c;调用签名 三&#…

人工智能深度学习入门指南

随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;深度学习作为其重要分支&#xff0c;已经成为许多领域的研究热点。深度学习通过模拟人脑神经网络的运作方式&#xff0c;使得机器能够处理和分析海量的数据&#xff0c;从而实现更高级别的智能。本文将为你提…

Rust入门问题: use of undeclared crate or module `rand`

按照官网学rust&#xff0c;程序地址在这里&#xff0c; 写个猜数字游戏 - Rust 程序设计语言 简体中文版 程序内容也很简单&#xff0c; use std::io; use rand::Rng;fn main() {println!("Guess the number!");let secret_number rand::thread_rng().gen_range…

SPI NOR FLASH和SPI NAND FLASH

SPI NOR FLASH和SPI NAND FLASH是两种不同的存储设备&#xff0c;它们在硬件接口和软件应用上都有所不同。以下是关于这两种存储设备更详细的介绍&#xff1a; 1.SPI NOR FLASH SPI NOR FLASH是一种非易失性存储器&#xff0c;它通过串行接口进行数据传输&#xff0c;具有读写…

VUE学习——事件修饰符

阻止默认事件 <template><a click"onClickHandle" href"https://www.baidu.com">baidu</a><a click.prevent"onClickHandle" href"https://www.baidu.com">baidu</a> </template> <script>…

IT行业有哪些证书含金量高?

1.Amazon Certified Cloud Practitioner 转码小白超友好的一门入门级证书&#xff0c;对于之前没有IT或者project经验的同学也可以轻轻松松顺利拿下&#xff0c;含金量很高可以直接标到linkedln的个人介绍里面。 (1)将如何帮助职业生涯 获得此认证可验证对 AWS Cloud、服务和…

真、开源LLM-OLMo

论文&#xff1a;https://arxiv.org/pdf/2402.00838.pdf Weights https://huggingface.co/allenai/OLMo-7B Code https://github.com/allenai/OLMo Data https://huggingface.co/datasets/allenai/dolma Evaluation https://github.com/allenai/OLMo-Eval Adaptation http…