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

当牛做吗网站源代码分享百度云帝国怎么做网站

当牛做吗网站源代码分享百度云,帝国怎么做网站,公司没有自己的网站,购物网页模板文章目录 4.智能指针[shared_ptr]4.1设计理念成员属性 4.2主要接口拷贝构造 4.3引用计数线程安全问题测试线程安全通过对计数引用的加锁保护使得类线程安全类实例化的对象使用时需要手动加锁保护 锁的引进线程引用传参问题 4.4整体代码 5.循环引用问题5.1问题的引入… 文章目录 4.智能指针[shared_ptr]4.1设计理念成员属性 4.2主要接口拷贝构造 4.3引用计数线程安全问题测试线程安全通过对计数引用的加锁保护使得类线程安全类实例化的对象使用时需要手动加锁保护 锁的引进线程引用传参问题 4.4整体代码 5.循环引用问题5.1问题的引入5.2分析造成此问题的原因5.3weak_ptr的主要代码 6.数组对象的删除问题6.1代码问题6.2std::shared_ptr面对此问题的解决方案1.首先看std::shared_ptr::~shared_ptr2.删除器的传参及使用3.添加封装删除器 7.总结7.1完整代码7.2C11和Boost智能指针的关系 4.智能指针[shared_ptr] 4.1设计理念 成员属性 每一个对象除了有一个主指针外 还有一个副指针用来计数 为什么不设置成int而设置成int*? 同一块空间被两个指针指向 当编译器得到需要销毁指针的指令时 会先判断这是不是最后一个指针 即count1 时才释放空间 其余情况均只是的计数-- 而不释放空间 这是我们的最初目的 如果设置成int意味着每一个对象有各自的count 当ptr1拷贝给ptr2 我们想要的是 有一块空间单独来计数 如果执行拷贝则计数 即我们需要一块共有的空间来实现 不是要实现共有吗 为什么不直接用静态变量? 静态变量可以实现共有没错 但他是当前类的所有对象共有 举例说明: 代码的本意是ptr1 ptr2 ptr3指向同一块空间 此时count 3 ptr4指向另一块空间时 代码的本意是count 1 但是同时改变了ptr1/2/3 4.2主要接口 拷贝构造 //赋值重载//1.自己给自己赋值//不仅仅是p1 p1 还要考虑p2 p1 但之前p2就 p1//2.左 右 赋值后 // 左指针指向空间的指针少了一个 左指针的count-- 进一步考虑count--后0的情况// 右指针指向空间的指针多了一个 右指针的countshared_ptrT operator(const shared_ptrT sp){//自己给自己赋值: 自己的本质if (_ptr ! sp._ptr){//count--Release();_ptr sp._ptr;_pcount sp._pcount;_pmtx sp._pmtx;//countAddCount();}return *this;}4.3引用计数线程安全问题 测试线程安全 通过对计数引用的加锁保护使得类线程安全 struct Date{int _year 0;int _month 0;int _day 0;};void SharePtrFunc(ape::shared_ptrDate sp, size_t n, mutex mtx){cout SharePtrFunc: sp.GetPtr() sp.GetPtr() endl;for (size_t i 0; i n; i){ape::shared_ptrDate copy(sp);}}void test_shared_safe(){ape::shared_ptrDate p(new Date);cout test_shared_safe: p.GetPtr() p.GetPtr() endl;const size_t n 10000;mutex mtx;//线程引用传参即便mtx已经是引用 此处仍然需要使用库函数ref();thread t1(SharePtrFunc, ref(p), n, ref(mtx));thread t2(SharePtrFunc, ref(p), n, ref(mtx));t1.join();t2.join();cout p.GetCount(): p.GetCount() endl;}类实例化的对象使用时需要手动加锁保护 锁的引进 线程引用传参问题 简单理解为 p在传给sp前是需要先调用线程的构造函数的 期间发生了某种动作 使得失去引用属性 4.4整体代码 templateclass T class shared_ptr { public://构造函数shared_ptr(T* ptr):_ptr(ptr), _pcount(new int(1)), _pmtx(new mutex){}void Release(){//上锁_pmtx-lock();//不可释放锁bool deleteFlag false;if (--(*_pcount) 0){cout delete: _ptr endl;delete _ptr;delete _pcount;//可释放锁deleteFlag true;}//解锁_pmtx-unlock();//判断并释放锁if (deleteFlag){delete _pmtx;}}//void Release()//{// _pmtx-lock();// bool deleteFlag false;// if (--(*_pcount) 0)// {// if (_ptr)// {// //cout delete: _ptr endl;// //delete _ptr;//// // 删除器进行删除// _del(_ptr);// }//// delete _pcount;// deleteFlag true;// }//// _pmtx-unlock();//// if (deleteFlag)// {// delete _pmtx;// }//}void AddCount(){_pmtx-lock();(*_pcount);_pmtx-unlock();}//拷贝构造shared_ptr(const shared_ptrT sp):_ptr(sp._ptr), _pcount(sp._pcount), _pmtx(sp._pmtx){AddCount();}//赋值重载//1.自己给自己赋值//不仅仅是p1 p1 还要考虑p2 p1 但之前p2就 p1//2.左 右 赋值后 // 左指针指向空间的指针少了一个 左指针的count-- 进一步考虑count--后0的情况// 右指针指向空间的指针多了一个 右指针的countshared_ptrT operator(const shared_ptrT sp){//自己给自己赋值: 自己的本质if (_ptr ! sp._ptr){//count--Release();_ptr sp._ptr;_pcount sp._pcount;_pmtx sp._pmtx;//countAddCount();}return *this;}//析构函数~shared_ptr(){Release();}T operator*(){return *_ptr;}T* operator-(){return _ptr;}T* GetPtr(){return _ptr;}int GetCount(){return *_pcount;}private:T* _ptr;int* _pcount;mutex* _pmtx; };void test_shared() {shared_ptrint sp1(new int(1));shared_ptrint sp2(sp1);shared_ptrint sp3(sp2);shared_ptrint sp4(new int(10));sp1 sp4;sp4 sp1;sp1 sp1;sp1 sp2; }// 线程安全问题 /// struct Date {int _year 0;int _month 0;int _day 0; };void SharePtrFunc(ape::shared_ptrDate sp, size_t n, mutex mtx) {cout SharePtrFunc: sp.GetPtr() sp.GetPtr() endl;cout SharePtrFunc: sp sp endl;for (size_t i 0; i n; i){ape::shared_ptrDate copy(sp);mtx.lock();sp-_year;sp-_day;sp-_month;mtx.unlock();} }void test_shared_safe() {ape::shared_ptrDate p(new Date);cout test_shared_safe: p.GetPtr() p.GetPtr() endl;cout test_shared_safe: p p endl;const size_t n 100000;mutex mtx;//线程引用传参即便p和mtx已经是引用 此处仍然需要使用库函数ref();thread t1(SharePtrFunc, ref(p), n, ref(mtx));thread t2(SharePtrFunc, ref(p), n, ref(mtx));t1.join();t2.join();cout p.GetCount(): p.GetCount() endl;cout p-_year p-_year endl;cout p-_month p-_month endl;cout p-_month p-_month endl;}5.循环引用问题 5.1问题的引入 5.2分析造成此问题的原因 为了解决此问题 需要引进weaked_ptr 我们需要了解的是 智能指针shared_ptr满足 符合RAII思想可以像指针一样使用支持拷贝 智能指针weaked_ptr满足 不符合RAII思想可以像指针一样使用辅助解决shared_ptr的循环引用问题weaked_ptr可以指向资源但是不参与管理不增加引用计数 实际上库里的智能指针远比我们上述讲到的复杂得多 为了便于学习和理解 我们只学习核心框架 需要了解的是 库里所支持的这两个函数 weaked_ptr有自己的count 配合expired来判断所指向资源是否还有被指向的必要 即weaked_ptr可以指向资源但是不参与管理不增加shared_ptr引用计数 所以存在于一种所指向资源的计数已经成0 此时expired判断是否失效 若所指向资源失效weaked_ptr就不再指向 5.3weak_ptr的主要代码 templateclass T class weak_ptr { public:weak_ptr():_ptr(nullptr){}weak_ptr(const shared_ptrT sp):_ptr(sp.GetPtr()){}T operator*(){return *_ptr;}T* operator-(){return _ptr;}T* GetPtr(){return _ptr;}private:T* _ptr; };6.数组对象的删除问题 6.1代码问题 ape::shared_ptrDate sparr(new Date[10]); 当使用我们自己模拟实现的简洁版shared_ptr时 上述代码会报错(手动实现Date的析构函数时会报错 不手动实现调用库的析构函数不报错 因为当手动实现了析构函数 Date的空间前会有一个4字节的空间用来存放实例化对象的个数 以便知道调用几次析构函数 但是此时析构函数应该先向前偏移4字节 以便析构时把这4个字节也释放 6.2std::shared_ptr面对此问题的解决方案 1.首先看std::shared_ptr::~shared_ptr 即库里的shared_ptr::~shared_ptr与我们写的析构函数不同之处在于 一个对象在实例化时 他会判断是否接受了参数deleter 如果接收则析构时调用deleter析构 若没有接收deleter则正常析构 2.删除器的传参及使用 销毁对象。但是以前根据成员use_count的值它可能会产生以下副作用如果use_count大于1即该对象与其他shared_ptr对象共享其托管对象的所有权与其共享所有权的其他对象的使用计数将减少1。如果use_coount为1即该对象是托管指针的唯一所有者它所拥有的指针被删除如果shared_ptr对象是用特殊的deleter构造的则调用它否则函数使用运算符delete。如果use_count为零即对象为空则此析构函数没有副作用。 templateclass Tstruct DeleteArray{void operator()(T* ptr){cout 匿名对象DeleteArrayDate(): ptr endl;delete[] ptr;}};void test_std_shared_deletor(){//template class U, class D //shared_ptr (U* p, D del); 带删除器的构造函数std::shared_ptrDate sparr1(new Date[10], DeleteArrayDate());std::shared_ptrDate sparr2(new Date[10],[](Date* ptr){cout lambda表达式 delete[]: ptr endl;delete[] ptr;});auto deleter [](Date* ptr){cout lambda表达式 delete[]: ptr endl;delete[] ptr;};std::shared_ptrDate sparr3(new Date[10], deleter);std::shared_ptrFILE spFile(fopen(Test.cpp, r),[](FILE* ptr){cout lambda表达式 delete[]: ptr endl;fclose(ptr);});}3.添加封装删除器 7.总结 7.1完整代码 #pragma once#include mutex #include thread #include memorynamespace ape {templateclass Tclass shared_ptr{public://构造函数shared_ptr(T* ptr nullptr):_ptr(ptr), _pcount(new int(1)), _pmtx(new mutex){}//删除器构造函数templateclass Dshared_ptr(T* ptr, D del):_ptr(ptr), _pcount(new int(1)), _pmtx(new mutex), _del(del){}//非删除器Release()/*void Release(){//上锁_pmtx-lock();//不可释放锁bool deleteFlag false;if (--(*_pcount) 0){if (_ptr ! nullptr){cout delete: _ptr endl;delete _ptr;}delete _pcount;//可释放锁deleteFlag true;}//解锁_pmtx-unlock();//判断并释放锁if (deleteFlag){delete _pmtx;}}*///删除器Release()void Release(){_pmtx-lock();bool deleteFlag false;if (--(*_pcount) 0){if (_ptr ! nullptr){_del(_ptr);}delete _pcount;deleteFlag true;}_pmtx-unlock();if (deleteFlag){delete _pmtx;}}void AddCount(){_pmtx-lock();(*_pcount);_pmtx-unlock();}//拷贝构造shared_ptr(const shared_ptrT sp):_ptr(sp._ptr), _pcount(sp._pcount), _pmtx(sp._pmtx){AddCount();}//赋值重载//1.自己给自己赋值//不仅仅是p1 p1 还要考虑p2 p1 但之前p2就 p1//2.左 右 赋值后 // 左指针指向空间的指针少了一个 左指针的count-- 进一步考虑count--后0的情况// 右指针指向空间的指针多了一个 右指针的countshared_ptrT operator(const shared_ptrT sp){//自己给自己赋值: 自己的本质if (_ptr ! sp._ptr){//count--Release();_ptr sp._ptr;_pcount sp._pcount;_pmtx sp._pmtx;//countAddCount();}return *this;}//析构函数~shared_ptr(){Release();}T operator*(){return *_ptr;}T* operator-(){return _ptr;}T* GetPtr() const{return _ptr;}int GetCount() const{return *_pcount;}private:T* _ptr;int* _pcount;mutex* _pmtx;//包装器//缺省值处理情况: ape::shared_ptrDate sp(new Date);//因为你析构时默认使用删除器 那么遇到没有显示传的要使用缺省值//构造函数传deleter时 可以是仿函数 lambda表达式 函数指针 此处用包装器接收functionvoid(T*) _del [](T* ptr){cout lambda表达式 delete: ptr endl;delete ptr;};};void test_shared(){shared_ptrint sp1(new int(1));shared_ptrint sp2(sp1);shared_ptrint sp3(sp2);shared_ptrint sp4(new int(10));sp1 sp4;sp4 sp1;sp1 sp1;sp1 sp2;}// 线程安全问题 ///struct Date{int _year 0;int _month 0;int _day 0;~Date(){}};void SharePtrFunc(ape::shared_ptrDate sp, size_t n, mutex mtx){cout SharePtrFunc: sp.GetPtr() sp.GetPtr() endl;cout SharePtrFunc: sp sp endl;for (size_t i 0; i n; i){ape::shared_ptrDate copy(sp);mtx.lock();sp-_year;sp-_day;sp-_month;mtx.unlock();}}void test_shared_safe(){ape::shared_ptrDate p(new Date);cout test_shared_safe: p.GetPtr() p.GetPtr() endl;cout test_shared_safe: p p endl;const size_t n 100000;mutex mtx;//线程引用传参即便p和mtx已经是引用 此处仍然需要使用库函数ref();thread t1(SharePtrFunc, ref(p), n, ref(mtx));thread t2(SharePtrFunc, ref(p), n, ref(mtx));t1.join();t2.join();cout p.GetCount(): p.GetCount() endl;cout p-_year p-_year endl;cout p-_month p-_month endl;cout p-_month p-_month endl;}templateclass Tclass weak_ptr{public:weak_ptr():_ptr(nullptr){}weak_ptr(const shared_ptrT sp):_ptr(sp.GetPtr()){}T operator*(){return *_ptr;}T* operator-(){return _ptr;}T* GetPtr(){return _ptr;}private:T* _ptr;};// 循环引用struct ListNode{/*普通写法ListNode* _next;ListNode* _prev;int _val;*//*shared_ptrape::shared_ptrListNode _next;ape::shared_ptrListNode _prev;int _val;*///weaked_ptrape::weak_ptrListNode _next;ape::weak_ptrListNode _prev;int _val;~ListNode(){cout ~ListNode() endl;}};// 循环引用void test_shared_cycle(){/*常规写法 -- 抛异常场景不适合ListNode* n1 new ListNode;ListNode* n2 new ListNode;n1-_next n2;n2-_prev n1;delete n1;delete n2;*///智能指针写法ape::shared_ptrListNode n1(new ListNode);ape::shared_ptrListNode n2(new ListNode);//内置类型 自定义类型 -- error/*ListNode* _next;ListNode* _prev;int _val;ape::shared_ptrListNode n1(new ListNode);ape::shared_ptrListNode n2(new ListNode);n1-_next n2;n2-_prev n1;*//*shared_ptr: 引发循环引用问题ape::shared_ptrListNode _next;ape::shared_ptrListNode _prev;int _val;ape::shared_ptrListNode n1(new ListNode);ape::shared_ptrListNode n2(new ListNode);n1-_next n2;n2-_prev n1;*//*weak_ptr: 解决循环引用ape::weak_ptrListNode _next;ape::weak_ptrListNode _prev;int _val;ape::shared_ptrListNode n1(new ListNode);ape::shared_ptrListNode n2(new ListNode);*/cout n1.GetCount() n1.GetCount() endl;cout n2.GetCount() n2.GetCount() endl;n1-_next n2;n2-_prev n1;cout n1.GetCount() n1.GetCount() endl;cout n2.GetCount() n2.GetCount() endl;}///定制删除器 -- 可调用对象templateclass Tstruct DeleteArray{void operator()(T* ptr){cout 匿名对象DeleteArrayDate(): ptr endl;delete[] ptr;}};//std库deleter的学习/*void test_std_shared_deletor(){//template class U, class D //shared_ptr (U* p, D del); 带删除器的构造函数std::shared_ptrDate sparr1(new Date[10], DeleteArrayDate());std::shared_ptrDate sparr2(new Date[10],[](Date* ptr){cout lambda表达式 delete[]: ptr endl;delete[] ptr;});auto deleter [](Date* ptr){cout lambda表达式 delete[]: ptr endl;delete[] ptr;};std::shared_ptrDate sparr3(new Date[10], deleter);std::shared_ptrFILE spFile(fopen(Test.cpp, r),[](FILE* ptr){cout lambda表达式 delete[]: ptr endl;fclose(ptr);});}*///删除器构造函数/*templateclass Dshared_ptr(T* ptr, D del):_ptr(ptr), _pcount(new int(1)), _pmtx(new mutex), _del(del){}*/void test_ape_shared_deleter(){ ape::shared_ptrDate sp(new Date);ape::shared_ptrDate sparr1(new Date[10], DeleteArrayDate());ape::shared_ptrDate sparr2(new Date[10], [](Date* ptr) {cout lambda表达式 delete[]: ptr endl;delete[] ptr;});auto deleter [](Date* ptr){cout lambda表达式 delete[]: ptr endl;delete[] ptr;};ape::shared_ptrDate sparr3(new Date[10], deleter);ape::shared_ptrFILE spFile(fopen(Test.cpp, r),[](FILE* ptr){cout lambda表达式 delete[]: ptr endl;fclose(ptr);});} } 7.2C11和Boost智能指针的关系 C 98 中产生了第一个智能指针auto_ptr.C boost给出了更实用的scoped_ptr/shared_ptr/weak_ptr.C TR1引入shared_ptr。[TR1不是标准版]C 11引入了unique_ptr/shared_ptr/weak_ptr。unique_ptr对应boost的scoped_ptr。[实现原理参考boost实现]
http://www.zqtcl.cn/news/624606/

相关文章:

  • 网站开站备案深圳创业补贴10万
  • 圆通我做网站拉上海建站系统
  • 对于做网站有什么要求新闻发布会视频
  • 网站建设专业就业前景成都房产信息网 官网
  • 西宁网站建设公司排行网站查询域名ip解析
  • 柳州企业网站开发公司如何做网站首页图
  • 刷赞网站空间免费深圳网站制作公司排名
  • 网站内部优化策略获取网站的路径
  • 网站群 优点今天西安最新通告
  • 惠济免费网站建设设计制作的广告公司
  • 做一个网站建设装潢设计属于什么专业
  • 水处理网站源码注册销售公司流程和费用
  • 诸城网站建设0536s整站优化seo排名点击
  • 企业建设网站需注意哪些内容苏州网站怎么做
  • 浏览器打开网站网站推广软件工具
  • 网站主题编辑工具WordPress公司网站策划方案
  • 做旅游网站选什么空间搜索引擎优化策略有哪些
  • 网站备案多少钱安全网站建设与服务的关系
  • 手机端网页设计尺寸规范优化seo排名
  • 做网站业务提成多少厦门十大装修公司排名榜
  • 为什么用开源建站wordpress rss 插件
  • 语文建设投稿网站南昌做网站的公司多不多
  • 石家庄网站建设的公司功能性质网站
  • 企业网站主页模板装饰公司名字起名大全
  • 马鞍山网站设计价格如何在微信公众号内部做网站
  • 申请网站建设经费的报告生态建设网站
  • 建网站要多少钱用自己的服务器河北工程大学网站开发成本
  • 宁波网站建站公司商务网站模块设计时前台基础设施建设不包括
  • 徐州免费网站制作怎么用阿里云服务器搭建wordpress
  • php猎奇源码 织梦新闻视频图片八卦娱乐趣事资讯门户网站模板html代码表格