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

无限资源免费观看大全/seo一键优化

无限资源免费观看大全,seo一键优化,云南百度公司,企业网站制作费做分录1.RAII 与引用计数了解 Objective-C/Swift 的程序员应该知道引用计数的概念。引用计数这种计数是为了防止内存泄露而产生的。 基本想法是对于动态分配的对象,进行引用计数,每当增加一次对同一个对象的引用,那么引用对象的引用计数就会增加一次…

1.RAII 与引用计数

了解 Objective-C/Swift 的程序员应该知道引用计数的概念。引用计数这种计数是为了防止内存泄露而产生的。 基本想法是对于动态分配的对象,进行引用计数,每当增加一次对同一个对象的引用,那么引用对象的引用计数就会增加一次, 每删除一次引用,引用计数就会减一,当一个对象的引用计数减为零时,就自动删除指向的堆内存。

在传统 C++ 中,『记得』手动释放资源,总不是最佳实践。因为我们很有可能就忘记了去释放资源而导致泄露。 所以通常的做法是对于一个对象而言,我们在构造函数的时候申请空间,而在析构函数(在离开作用域时调用)的时候释放空间, 也就是我们常说的 RAII 资源获取即初始化技术。

凡事都有例外,我们总会有需要将对象在自由存储上分配的需求,在传统 C++ 里我们只好使用 new 和 delete 去 『记得』对资源进行释放。而 C++11 引入了智能指针的概念,使用了引用计数的想法,让程序员不再需要关心手动释放内存。 这些智能指针包括 std::shared_ptr/std::unique_ptr/std::weak_ptr,使用它们需要包含头文件 <memory>。

注意:引用计数不是垃圾回收,引用计数能够尽快收回不再被使用的对象,同时在回收的过程中也不会造成长时间的等待, 更能够清晰明确的表明资源的生命周期。

2.智能指针

从比较简单的层面来看,智能指针是RAII(Resource Acquisition Is Initialization,资源获取即初始化)机制对普通指针进行的一层封装。这样使得智能指针的行为动作像一个指针,本质上却是一个对象,这样可以方便管理一个对象的生命周期。

在c++中,一共定义了4种类型的智能指针:auto_ptr、unique_ptr、shared_ptr 和 weak_ptr。其中,auto_ptr 在 C++11已被摒弃,在C++17中已经移除不可用。下文对后三种智能指针进行对比。

2.1std::shared_ptr

std::shared_ptr 是一种智能指针,它能够记录多少个 shared_ptr 共同指向一个对象,从而消除显式的调用 delete,当引用计数变为零的时候就会将对象自动删除。

但还不够,因为使用 std::shared_ptr 仍然需要使用 new 来调用,这使得代码出现了某种程度上的不对称。

std::make_shared 就能够用来消除显式的使用 new,所以std::make_shared 会分配创建传入参数中的对象, 并返回这个对象类型的std::shared_ptr指针。例如:

#include<iostream>
#include<memory>
voidfoo(std::shared_ptr<int> i){(*i)++;
}
int main(){
// auto pointer = new int(10); // illegal, no direct assignment
// Constructed a std::shared_ptr
auto pointer = std::make_shared<int>(10);
foo(pointer);std::cout << *pointer << std::endl; // 11
// The shared_ptr will be destructed before leaving the scope
return0;
}

std::shared_ptr 可以通过 get() 方法来获取原始指针,通过 reset() 来减少一个引用计数, 并通过use_count()来查看一个对象的引用计数。例如:

auto pointer = std::make_shared<int>(10);
auto pointer2 = pointer; // 引用计数+1
auto pointer3 = pointer; // 引用计数+1
int *p = pointer.get();  // 这样不会增加引用计数
std::cout << "pointer.use_count() = " << pointer.use_count() << std::endl;   // 3
std::cout << "pointer2.use_count() = " << pointer2.use_count() << std::endl; // 3
std::cout << "pointer3.use_count() = " << pointer3.use_count() << std::endl; // 3pointer2.reset();
std::cout << "reset pointer2:" << std::endl;
std::cout << "pointer.use_count() = " << pointer.use_count() << std::endl;   // 2
std::cout << "pointer2.use_count() = "<< pointer2.use_count() << std::endl;           // pointer2 已 reset; 0
std::cout << "pointer3.use_count() = " << pointer3.use_count() << std::endl; // 2
pointer3.reset();
std::cout << "reset pointer3:" << std::endl;
std::cout << "pointer.use_count() = " << pointer.use_count() << std::endl;   // 1
std::cout << "pointer2.use_count() = " << pointer2.use_count() << std::endl; // 0
std::cout << "pointer3.use_count() = "<< pointer3.use_count() << std::endl;           // pointer3 已 reset; 0

2.2std::unique_ptr

std::unique_ptr 是一种独占的智能指针,它禁止其他智能指针与其共享同一个对象,从而保证代码的安全:

std::unique_ptr<int> pointer = std::make_unique<int>(10); //make_unique 从C++14开始引入
std::unique_ptr<int> pointer2 = pointer; // 非法
make_unique 并不复杂,C++11 没有提供 std::make_unique,可以自行实现:

至于为什么没有提供,C++ 标准委员会主席 Herb Sutter 在他的博客中提到原因是因为『被他们忘记了』。

既然是独占,换句话说就是不可复制。但是,我们可以利用 std::move 将其转移给其他的 unique_ptr,例如:

#include<iostream>
#include<memory>struct Foo {
Foo() { std::cout << "Foo::Foo" << std::endl; }~Foo() { std::cout << "Foo::~Foo" << std::endl; }
voidfoo(){ std::cout << "Foo::foo" << std::endl; }
};voidf(const Foo &){std::cout << "f(const Foo&)" << std::endl;
}int main(){
std::unique_ptr<Foo> p1(std::make_unique<Foo>());
// p1 不空, 输出
if (p1) p1->foo();{
std::unique_ptr<Foo> p2(std::move(p1));
// p2 不空, 输出
f(*p2);
// p2 不空, 输出
if(p2) p2->foo();
// p1 为空, 无输出
if(p1) p1->foo();p1 = std::move(p2);
// p2 为空, 无输出
if(p2) p2->foo();std::cout << "p2 被销毁" << std::endl;}
// p1 不空, 输出
if (p1) p1->foo();
// Foo 的实例会在离开作用域时被销毁
}

2.3 std::weak_ptr

如果你仔细思考 std::shared_ptr 就会发现依然存在着资源无法释放的问题。看下面这个例子:

struct A;
struct B;struct A {std::shared_ptr<B> pointer;~A() {std::cout << "A 被销毁" << std::endl;}
};
struct B {std::shared_ptr<A> pointer;~B() {std::cout << "B 被销毁" << std::endl;}
};
int main(){
auto a = std::make_shared<A>();
auto b = std::make_shared<B>();a->pointer = b;b->pointer = a;
}

运行结果是 A, B 都不会被销毁,这是因为 a,b 内部的 pointer 同时又引用了 a,b,这使得 a,b 的引用计数均变为了 2,而离开作用域时,a,b 智能指针被析构,却只能造成这块区域的引用计数减一,这样就导致了 a,b 对象指向的内存区域引用计数不为零,而外部已经没有办法找到这块区域了,也就造成了内存泄露,如下图1所示:

解决这个问题的办法就是使用弱引用指针 std::weak_ptr,std::weak_ptr是一种弱引用(相比较而言 std::shared_ptr 就是一种强引用)。弱引用不会引起引用计数增加,当换用弱引用时候,最终的释放流程如图 2所示:

在上图中,最后一步只剩下 B,而 B 并没有任何智能指针引用它,因此这块内存资源也会被释放。

std::weak_ptr 没有 * 运算符和 -> 运算符,所以不能够对资源进行操作,它可以用于检查 std::shared_ptr 是否存在,其 expired() 方法能在资源未被释放时,会返回 false,否则返回 true;除此之外,它也可以用于获取指向原始对象的 std::shared_ptr 指针,其 lock() 方法在原始对象未被释放时,返回一个指向原始对象的 std::shared_ptr 指针,进而访问原始对象的资源,否则返回nullptr。

3.总结

智能指针这种技术并不新奇,在很多语言中都是一种常见的技术,现代 C++ 将这项技术引进,在一定程度上消除了 new/delete 的滥用,是一种更加成熟的编程范式。

4. 其它

  1. stackoverflow 上关于『C++11为什么没有 make_unique』的讨论

相关文章:

C++中的智能指针

1.RAII 与引用计数了解 Objective-C/Swift 的程序员应该知道引用计数的概念。引用计数这种计数是为了防止内存泄露而产生的。 基本想法是对于动态分配的对象&#xff0c;进行引用计数&#xff0c;每当增加一次对同一个对象的引用&#xff0c;那么引用对象的引用计数就会增加一次…...

LSTM已死,Transformer当立(LSTM is dead. Long Live Transformers! ):下

2017 年,Google 在论文 Attention is All you need 中提出了 Transformer 模型,其使用 Self-Attention 结构取代了在 NLP 任务中常用的 RNN 网络结构。而且实验也证明Transformer 在效果上已经完败传统的 RNN 网络。Transformer 的整体模型架构如下图所示。尽管它看起来还是很…...

OJ万题详解––[NOIP2004 提高组] 合并果子(C++详解)

目录 题目 分析 参考代码 题目 题目描述 一个果园里&#xff0c;多多已经将所有的果子打了下来&#xff0c;而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。 每一次合并&#xff0c;多多可以把两堆果子合并到一起&#xff0c;消耗的体力等于两堆果子的…...

MySQL-字符集和比较规则

在计算机中只能存储二进制数据&#xff0c;那该怎么存储字符串呢&#xff1f;当然是建立字符与二进制数据的映射关系 了&#xff0c;建立这个关系最起码要搞清楚两件事&#xff1a; 界定清楚字符范围&#xff1a;需要把哪些字符映射成二进制数据&#xff1f;编码与解码&#x…...

微搭低代码从入门到精通12-网格布局

开发小程序首要的就是考虑布局的问题&#xff0c;我们在以前的版本只能选择普通容器结合图片和文本组件来构建页面。 使用通用组件布局也可以&#xff0c;但有个问题是你要先学习CSS&#xff0c;要懂布局的概念&#xff0c;比如需要知道啥是flex布局&#xff0c;然后还得熟悉每…...

【c语言】二叉树

主页&#xff1a;114514的代码大冒险 qq:2188956112&#xff08;欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ &#xff09; Gitee&#xff1a;庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 引入 我们之前已经学过线性数据结构&#xff0c;今天我们将介绍非线性数据结构----树 树是一种非线性的…...

六、Java框架之SpringBoot

黑马课程 文章目录1. SpringBoot入门1.1 SpringBoot入门案例步骤1&#xff1a;创建SpringBoot项目高版本springboot常见错误步骤2&#xff1a;创建BookController步骤3&#xff1a;启动服务器并运行程序pom.xml示例1.2 官网创建SpringBoot1.3 SpringBoot工程快速启动问题导入打…...

「Python|环境安装|Windows」如何在Windows上安装Python环境?

本文主要介绍如何在Windows上安装Python&#xff0c;帮助初学者或者非程序员伙伴快速搭建可以运行python代码的环境。 文章目录安装python做一点小配置验证python如何安装指定版本的python编程语言的环境搭建一直是学习编程的第一道门槛。 对于如何在Linux系统上安装指定版本的…...

人工智能轨道交通行业周刊-第33期(2023.2.6-2.12)

本期关键词&#xff1a;高铁激光清洗、高铁确认列车、无线通信系统、推理服务优化、量子信息技术 1 整理涉及公众号名单 1.1 行业类 RT轨道交通中关村轨道交通产业服务平台人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟V…...

五分钟看懂Java字节码:极简手册

字节码新手很容易被厚厚的 JVM 书籍劝退&#xff0c;即使我看过相关书籍&#xff0c;工作真正用到时也全忘了&#xff0c;还得现学。 等我有了一定的字节码阅读经验&#xff0c;才发现字节码其实非常简单&#xff0c;只需要三步就能快速学会&#xff1a; 先了解 JVM 的基本结…...

C++ 类与对象(下)

✅<1>主页&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;C &#x1f525;<3>创作者&#xff1a;我的代码爱吃辣 ☂️<4>开发环境&#xff1a;Visual Studio 2022 &#x1f4ac;<5>前言&#xff1a;C类与对象的收尾工作&#…...

Java基础——I/O

一、异常 异常是程序中可能出现的问题&#xff0c;它的父类是Exception。异常分为两类&#xff0c;编译时异常、运行时异常。 编译时异常&#xff1a;没有继承RuntimeException的异常&#xff0c;直接继承于Exception。编译阶段就会错误提示。运行时异常&#xff1a;RuntimeE…...

关于@hide的理解

在上一篇文章《学习HandlerThread》我们提到虽然HandlerThread类里有getThreadHandler()方法得到Handler&#xff0c;但是我们不可能调用到它。因为这个方法用hide注释了 /*** return a shared {link Handler} associated with this thread* hide*/NonNullpublic Handler getT…...

使用python加密主机文件几种方法实现

本文主要介绍了使用python加密主机文件几种方法实现&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧数据加密是一种保护数据安全的技术&#xff0c;通过对数据进行编…...

西湖论剑 2023 比赛复现

WEB real_ez_node 在 route/index.js 中&#xff1a; router.post(/copy,(req,res)>{res.setHeader(Content-type,text/html;charsetutf-8)var ip req.connection.remoteAddress;console.log(ip);var obj {msg: ,}if (!ip.includes(127.0.0.1)) {obj.msg"only for…...

微信小程序更换管理员/重置管理员

方式1&#xff1a; 首先进入微信公众平台官网进入并登录后在管理中找到成员管理选项找到管理员点击后方的修改选项需要使用原管理员的微信进行扫码验证扫码后在手机上确认绑定新管理员&#xff0c;注意&#xff1a;如果是个人账号不可以更改成其他人。 方式2&#xff1a;原管…...

企业进存销管理系统

技术&#xff1a;Java、JSP等摘要&#xff1a;随着当今世界计算机技术的飞速发展&#xff0c;计算机在企业管理中应用的普及&#xff0c;利用计算机实现企业进销存管理势在必行。本系统结合公司实际的进销存制度&#xff0c;通过对本公司的供应商、客户、商品、进货、销售、进销…...

C++入门

变量变量创建的语法: 数据类型 变量名 变量初始值;int a 10;cout << a << endl;常量作用:用于记录程序中不可更改的教国C定义常量两种方式1).#define 宏常量:#define 常量名 常量值通常在文件上方定义。表示一个常量2).const 修饰的变量const 数据类型 常量名 常…...

视频知识点(20)- H264码流如何在SPS中获取宽高信息?

《音视频开发》系列-总览 前沿 了解H264视频编码格式的小伙伴都知道,H264编码中存在两个非常重要的参数集。没错,它们就是序列参数集(SPS)和图像参数集(PPS),而且通常情况下,PPS会依赖SPS中的部分参数信息,同时,视频码流的宽高信息也存储在SPS中。那么如何从中获取视…...

鲜花数据集实验结果总结

从read_split_data中得到&#xff1a;训练数据集&#xff0c;验证数据集&#xff0c;训练标签&#xff0c;验证标签。的所有的具体详细路径 数据集位置&#xff1a;https://download.csdn.net/download/guoguozgw/87437634 import os #一种轻量级的数据交换格式&#xff0c; …...

ElasticJob-Lite架构篇 - 认知分布式任务调度ElasticJob-Lite

前言 本文基于 ElasticJob-Lite 3.x 版本展开分析。 如果 Quartz 集群中有多个服务端节点&#xff0c;任务决定在哪个服务端节点上执行的呢&#xff1f; Quartz 采用随机负载&#xff0c;通过 DB 抢占下一个即将触发的 Trigger 绑定的任务的执行权限。 在 Quartz 的基础上&…...

【直击招聘C++】2.6 对象之间的复制

2.6 对象之间的复制一、要点归纳1. 对象之间的复制操作1.1 运算符1.2 拷贝构造函数2. 对象之间的浅复制和深复制2.1 对象的浅复制2.2 对象的深复制二、面试真题解析面试题1面试题2一、要点归纳 1. 对象之间的复制操作 同一个类的对象之间可以进行复制操作&#xff0c;即将一个…...

学了这么久python,不会连自己啥python版本都不知道吧?

人生苦短&#xff0c;我用Python 源码资料电子书:点击此处跳转文末名片获取 查看 Python 版本 我们可以在命令窗口(Windows 使用 winR 调出 cmd 运行框)使用以下命令查看我们使用的 Python 版本&#xff1a; python -V 或 python --version 以上命令执行结果如下&#xff1a; …...

Revive:从间谍软件进化成银行木马

2022 年 6 月&#xff0c;Cleafy 研究人员发现了一个新的安卓银行木马 Revive。之所以选择 Revive 这个名称&#xff0c;是因为恶意软件为防止停止工作启用的一项功能名为 revive。 Revive 属于持续潜伏的那一类恶意软件&#xff0c;因为它是为特定目标开发和定制的。这种类型…...

Python 之 NumPy 简介和创建数组

文章目录一、NumPy 简介1. 为什么要使用 NumPy2. NumPy 数据类型3. NumPy 数组属性4. NumPy 的 ndarray 对象二、numpy.array() 创建数组1. 基础理论2. 基础操作演示3. numpy.array() 参数详解三、numpy.arange() 生成区间数组四、numpy.linspace() 创建等差数列五、numpy.logs…...

与六年测试工程师促膝长谈,他分享的这些让我对软件测试工作有了全新的认知~

不知不觉已经从事软件测试六年了&#xff0c;2016年毕业到进入外包公司外包给微软做软件测试&#xff0c; 到现在加入著名的外企。六年的时间过得真快。长期的测试工作也让我对软件测试有了比较深入的认识。但是我至今还是一个底层的测试人员&#xff0c;我的看法都比较狭隘&am…...

裕太微在科创板上市:市值约186亿元,哈勃科技和小米基金为股东

2月10日&#xff0c;裕太微电子股份有限公司&#xff08;下称“裕太微”&#xff0c;SH:688515&#xff09;在上海证券交易所上市。本次上市&#xff0c;裕太微的发行价为92元/股&#xff0c;发行2000万股&#xff0c;发行市盈率不适用&#xff0c;发行后总股本8000万股。 根据…...

毕业后5年,我终于变成了月薪13000的软件测试工程师

我用了近2个月的时间转行&#xff0c;在今年1月底顺利入职了一家北京的互联网公司&#xff0c;从事的是软件测试的工作。 和大家看到的一样&#xff0c;我求职的时间花费的比较短&#xff0c;求职过程非常顺利&#xff0c;面试了一周就拿到了3家offer&#xff0c;3家offer的薪…...

实践指南|如何在 Jina 中使用 OpenTelemetry 进行应用程序的监控和跟踪

随着软件和云技术的普及&#xff0c;越来越多的企业开始采用微服务架构、容器化、多云部署和持续部署模式&#xff0c;这增加了因系统失败而给运维/ SRE / DevOps 团队带来的压力&#xff0c;从而增加了开发团队和他们之间的摩擦&#xff0c;因为开发团队总是想尽快部署新功能&…...

MySQL 创建数据表

在创建数据库之后&#xff0c;接下来就要在数据库中创建数据表。所谓创建数据表&#xff0c;指的是在已经创建的数据库中建立新表。 创建数据表的过程是规定数据列的属性的过程&#xff0c;同时也是实施数据完整性&#xff08;包括实体完整性、引用完整性和域完整性&#xff09…...