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

福州模板建站定制网站宿州网站建设报价

福州模板建站定制网站,宿州网站建设报价,网站服务器维护工具,什么是网络营销?💓个人主页:mooridy 💓专栏地址:C 关注我🌹,和我一起学习更多计算机的知识 🔝🔝🔝 什么是智能指针? 智能指针是 C 中一种用于管理动态内存的机制。它提供了一…

💓个人主页:mooridy
💓专栏地址:C++
关注我🌹,和我一起学习更多计算机的知识
🔝🔝🔝

什么是智能指针?

智能指针是 C++ 中一种用于管理动态内存的机制。它提供了一种更安全、更方便的方式来处理对象的生命周期,自动释放不再需要的内存,从而避免内存泄漏和悬空指针等问题。

为什么要有智能指针?

你可能会想,智能指针虽然方便,但也不是必须的呀?我只要自己记得释放就好了。但有的时候,我们会遇到如下面代码这样无解的问题。

我们在int* p1 = new int,int* p2 = new int,div()这三个地方都有可能发生抛异常导致无法执行后续代码,即无法释放掉申请的空间,造成内存泄露。

这时我们就需要引入智能指针。

int div()
{int a, b;cin >> a >> b;if (b == 0)throw invalid_argument("除0错误");return a / b;
}
void Func()
{// 1、如果p1这里new 抛异常会如何?// 2、如果p2这里new 抛异常会如何?// 3、如果div调用这里又会抛异常会如何?int* p1 = new int;int* p2 = new int;cout << div() << endl;delete p1;delete p2;
}
int main()
{try{Func();}catch (exception& e){cout << e.what() << endl;}return 0;
}

RAII思想

RAII是`是⼀种管理资源的类的设计思想,本质是⼀种利⽤对象⽣命周期来管理获取到的动态资源,避免资源泄漏,这⾥的资源可以是内存、⽂件指针、⽹络连接、互斥锁等等。RAII在获取资源时把资源委托给⼀个对象,接着控制对资源的访问,资源在对象的⽣命周期内始终保持有效,最后在对象析构的时候释放资源,这样保障了资源的正常释放,避免资源泄漏问题。

智能指针的设计就是依据RAII思想。

智能指针的基本思想

我们知道当对象出了作用域会自动调用析构,那么我们就把申请资源放在构造函数里,把释放资源放在析构函数里。

// 使用RAII思想设计的SmartPtr类
template<class T>
class SmartPtr {
public:    
SmartPtr(T* ptr = nullptr)    : _ptr(ptr)    
{}
~SmartPtr()    
{if(_ptr!=nullptr)    delete _ptr;    
}
T& operator*() {return *_ptr;}    
T* operator->() {return _ptr;}    
private:    T* _ptr;    
};

C++标准库中的几种智能指针

• C++标准库中的智能指针都在这个头⽂件下面。

auto_ptr是C++98时设计出来的智能指针,他的特点是拷⻉时把被拷⻉对象的资源的管理权转移给

拷⻉对象,这是⼀个⾮常糟糕的设计,因为他会到被拷⻉对象悬空,访问报错的问题。强烈建议不要使⽤auto_ptr

#include <iostream>
#include <memory>int main() { // 创建一个 std::auto_ptr 并让它管理一个 int 对象std::auto_ptr<int> ptr1(new int(42)); // 输出 ptr1 所指向的值std::cout << "ptr1 value before copy: " << *ptr1 << std::endl;// 拷贝 ptr1 到 ptr2,此时 ptr1 的资源管理权转移给 ptr2std::auto_ptr<int> ptr2(ptr1);// 尝试访问 ptr1 所指向的值,这会导致未定义行为// 因为 ptr1 已经失去了对资源的管理权,变成了悬空指针std::cout << "ptr1 value after copy: " << *ptr1 << std::endl;return 0;
}    

unique_ptr是C++11设计出来的智能指针,他的特点的不⽀持拷⻉,只⽀持移动。

shared_ptr是C++11设计出来的智能指针,他的特点是⽀持拷⻉,也⽀持移动。底层是⽤引⽤计数的⽅式实现的。

weak_ptr是C++11设计出来的智能指针,他完全不同于上⾯的智能指

针,他不⽀持RAII,也就意味着不能⽤它直接管理资源,weak_ptr的产⽣本质是要解决shared_ptr

的⼀个循环引⽤导致内存泄漏的问题。(这个问题文章后面会谈到)

shared_ptr的模拟实现

这段代码经常面试手撕,一定要会!
这⾥⼀份资源就需要⼀个引⽤计数,多个资源时引⽤计数⽤静态成员的⽅式是⽆法实现的,所以要使⽤堆上动态开辟的⽅式,构造智能指针对象时来⼀份资源,就要new⼀个引⽤计数出来。多个shared_ptr指向资源时就++引⽤计数,shared_ptr对象析构时就–引⽤计数,引⽤计数减到0时代表当前析构的shared_ptr是最后⼀个管理资源的对象,则析构资源。

#include <iostream>
#include <mutex>template<class T>
class Smart_Ptr // 实现的 C++11 的 shared_ptr 版本
{
public:// 构造函数,默认参数为 nullptr// 接收一个指向类型 T 对象的指针 ptr,用于初始化智能指针所管理的资源// 同时创建一个新的计数器,初始值为 1,表示当前只有一个智能指针管理该资源Smart_Ptr(T* ptr = nullptr): _ptr(ptr), _pcount(new int(1)){}// 析构函数// 当智能指针对象生命周期结束时,调用 Release 函数来处理资源的释放~Smart_Ptr(){Release();}// 拷贝构造函数// 接收另一个 Smart_Ptr 对象的引用 sp// 将当前智能指针的 _ptr 和 _pcount 指向 sp 的对应成员// 并调用 Addcount 函数将引用计数加 1Smart_Ptr(const Smart_Ptr<T>& sp): _ptr(sp._ptr), _pcount(sp._pcount){Addcount();}// 赋值运算符重载// 接收另一个 Smart_Ptr 对象的引用 sp// 首先检查是否是自我赋值(即 this 和 sp 是否指向同一个对象)// 如果不是,则先调用 Release 函数释放当前智能指针管理的资源// 然后将 _ptr 和 _pcount 指向 sp 的对应成员// 最后调用 Addcount 函数将引用计数加 1Smart_Ptr<T>& operator=(const Smart_Ptr<T>& sp){if (this != &sp) // 避免自我赋值{Release();_ptr = sp._ptr;_pcount = sp._pcount;Addcount();}return *this;}// 释放资源的函数// 首先对引用计数进行减 1 操作// 如果减 1 后引用计数变为 0,表示没有智能指针再管理该资源// 此时释放 _ptr 指向的资源、_pcount 指向的计数器void Release(){if (--(*_pcount) == 0) // 销毁最后一个变量时才释放资源{delete _ptr;delete _pcount;delete _pmtx;}}// 增加引用计数的函数// 对引用计数进行加 1 操作void Addcount(){(*_pcount)++;  }void Subcount()  {Release();   }private:   T* _ptr; // 指向实际管理的资源的指针int* _pcount; // 指向引用计数的指针,用于记录有多少个智能指针管理该资源};

shared_ptr的循环引用问题

下面这段代码演示的就是循环引用问题。

struct ListNode 
{
int _data; 
std::shared_ptr<ListNode> _next; 
std::shared_ptr<ListNode> _prev; 
// 这⾥改成weak_ptr,当n1->_next = n2;绑定shared_ptr时// 不增加n2的引⽤计数,不参与资源释放的管理,就不会形成循环引⽤了/*std::weak_ptr<ListNode> _next; 
std::weak_ptr<ListNode> _prev;*/
~ListNode()
{
cout << "~ListNode()" << endl;
}
};
int main()
{
// 循环引⽤ -- 内存泄露
std::shared_ptr<ListNode> n1(new ListNode);
std::shared_ptr<ListNode> n2(new ListNode);
cout << n1.use_count() << endl;
cout << n2.use_count() << endl;
n1->_next = n2;
n2->_prev = n1;
cout << n1.use_count() << endl;
cout << n2.use_count() << endl;
// weak_ptr不⽀持管理资源,不⽀持RAII
// weak_ptr是专⻔绑定shared_ptr,不增加他的引⽤计数,作为⼀些场景的辅助管理
//std::weak_ptr<ListNode> wp(new ListNode);
return 0;
}

这里我画了个图帮助理解。在这里插入图片描述

对于这种场景,最好的解决方案就是不要在这里使用智能指针!!!

weak_ptr不⽀持RAII,也不⽀持访问资源,weak_ptr构造时不⽀持绑定到资源,只⽀持绑定到shared_ptr,绑定到shared_ptr时,不增加shared_ptr的引⽤计数,也可以解决上述的循环引⽤问题。

weak_ptr也没有重载operator*operator->等,因为他不参与资源管理,那么如果他绑定的
shared_ptr已经释放了资源,那么他去访问资源就是很危险的。weak_ptr⽀持expired检查指向的资源是否过期,use_count也可获取shared_ptr的引⽤计数,weak_ptr想访问资源时,可以调⽤lock返回⼀个管理资源的shared_ptr,如果资源已经被释放,返回的shared_ptr是⼀个空对象,如果资源没有释放,则通过返回的shared_ptr访问资源是安全的。


文章转载自:

http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://00000000.qxmys.cn
http://www.dtcms.com/wzjs/615839.html

相关文章:

  • 中国那个公司的网站做的最好看汕头新闻头条最新消息
  • 网站后台如何做产品展示网站建设最好用什么语言
  • 天津百度做网站多少钱镇江vi设计
  • 装修设计网站哪个好用正规网站建设公司多少钱
  • 做家具城网站的意义阜新旅游网站建设
  • 哪个网站是免费的网站文件名优化
  • 怎么查看网站备案琪觅公司网站开发
  • 怎么能自己做网站国外空间租用
  • 美橙互联建站门户网站价格
  • 苏州 网站建设佛山市住房和建设局网站首页
  • 视频直播网站开发与制作wordpress表格图表插件
  • 手机网站php源码免费试用网站源码
  • 中企动力网站建设合同wordpress logo在哪里改
  • 网站联盟名词解释杭州百度推广优化排名
  • 江门网站免费制作微信公众号商城开发费用
  • 网站好做吗高端网页游戏
  • seo工作湖南厦门网站优化
  • 自助网站建设用什么好wordpress 动态加载
  • 多新闻怎么做扁平网站wordpress 图片加水印插件
  • 培训网站方案wordpress 显示商品
  • 网站统计 中文域名网页代理app
  • p2p倒闭 网站开发网站模版调用标签教程
  • 自己做开奖网站wordpress高级文章编辑器
  • 建个人网站一般多少钱淮安市住房和城乡建设局网站
  • 网站设计思路下载asp做网站
  • 做酒店网站的公司有域名自己做网站吗
  • 贵州省建设厅官网站wordpress 链接提交
  • php网站开发简介数据库网站开发
  • 建设旅游业网站目的财务公司名称大全简单大气
  • wordpress更改网站内容做seo网站地图重要吗