array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 资源共享型智能指针实现方式 - 爱码网

【1】资源共享型智能指针实现方式简述

资源共享型的智能指针有两种实现方式:一种是侵入式;一种是非侵入式。

 

网上以及书籍比较常见的是非侵入式的,它的实现完全放在智能指针模板类内。

模板类有一个用于保存资源类对象的指针变量和一个用于记录资源对象引用计数的指针变量。

两者是所有的智能指针对象共享的,所以通过指针保存。

 

侵入式则不同,它的实现分散在智能指针模板和使用资源对象类中:

模板类只有一个用于保存资源对象的指针变量,资源对象的引用计数却放在资源对象类中。

 

非侵入式智能指针,它的引用计数变量为了保证所有对象共享,需要用堆里的内存。

因此需要用new,其实这点两者都一样,不一样的是使用new的次数。

侵入式智能指针的引用计数变量保存在资源对象内,因为对象是唯一的,所以引用计数也是唯一的。

相比非侵入式智能指针,侵入式智能指针的利弊:

优点:

1> 一个资源对象无论被多少个侵入式智能指针包含,从始至终只有一个引用计数变量。

不需要在每一个使用智能指针对象的地方都new一个计数对象,这样子效率比较高,使用内存也比较少,且比较安全;

2> 因为引用计数存储在资源对象本身,所以在函数调用的时候可以直接传递资源对象地址,而不用担心引用计数值丢失。

(非侵入式智能指针对象的拷贝,必须带着智能指针模板,否则就会出现对象引用计数丢失)。

缺点:

1> 资源对象类必须有引用计数变量,并且该变量的增减允许被侵入式智能指针模板类操作。

2> 如果该资源类对象并不没有必要使用智能指针时,它还是会带着引用计数变量。

【2】侵入式智能指针实现

1>实现代码如下:

  1 #include <iostream>
  2 using namespace std;
  3 
  4 template< class T >
  5 class smartPtr 
  6 { 
  7 public:
  8     smartPtr(T* ptr) 
  9     {
 10         m_ptr = ptr;
 11         if (m_ptr != NULL)
 12             m_ptr->AddRef();
 13     }
 14     smartPtr(const smartPtr<T>& spObj)
 15     {
 16         m_ptr = spObj.m_ptr;
 17         if (m_ptr)
 18             m_ptr->AddRef();
 19     }
 20     ~smartPtr()
 21     {
 22         if (m_ptr != NULL) 
 23         {
 24             m_ptr->Release();
 25             m_ptr = NULL;
 26         }
 27     }
 28 
 29     T* operator->() const 
 30     {
 31         return m_ptr;
 32     }
 33 
 34     T* Get() const
 35     { 
 36         return m_ptr; 
 37     }
 38 private:
 39     T* m_ptr;
 40 };
 41 
 42 
 43 class Int
 44 {
 45 public:
 46     Int(int value) : m_nValue(value)
 47     {
 48         m_pCount = new int(0);
 49         std::cout <<"Construct: "<<this<<std::endl;
 50     }
 51 
 52     ~Int()
 53     {
 54         std::cout <<"Destruct: "<<this<<std::endl;
 55     }
 56 
 57     void AddRef()
 58     {
 59         (*m_pCount)++;
 60     }
 61 
 62     void Release()
 63     {
 64         --(*m_pCount);
 65         if ((*m_pCount) == 0)
 66         {
 67             delete this;
 68         }
 69     }
 70 
 71     int GetCount()
 72     {
 73         return (*m_pCount);
 74     }
 75 
 76 private:
 77     int* m_pCount;
 78     int m_nValue;
 79 };
 80 
 81 void TestTwo(Int* ptr)
 82 {
 83     smartPtr<Int> spTemp = ptr;
 84     std::cout<<spTemp->GetCount()<<" "<<spTemp.Get()<<std::endl; //计数为2
 85     smartPtr<Int> spObj = spTemp;
 86     std::cout<<spObj->GetCount()<<" "<<spTemp.Get()<<std::endl;  //计数为3
 87 }
 88 
 89 void TestOne()
 90 {
 91     Int* pInt = new Int(10);
 92     smartPtr<Int> spInt = pInt;
 93     std::cout<<spInt->GetCount()<<" "<<spInt.Get()<<std::endl; //计数为1
 94     TestTwo(pInt);
 95     std::cout<<spInt->GetCount()<<" "<<spInt.Get()<<std::endl; //计数为1
 96 }
 97 
 98 void main()
 99 {
100     TestOne();
101 }
102 
103 //执行结果如下:
104 /*
105 Construct: 009749E0
106 1 009749E0
107 2 009749E0
108 3 009749E0
109 1 009749E0
110 Destruct: 009749E0
111 */

以上为不完整代码实现,仅仅为了理解侵入式智能指针而已。

 

Good Good Study, Day Day Up.

顺序  选择  循环 总结

相关文章: