东营网站设计公司,3000ok新开传奇网站,做毕业设计网站的问题与展望,打开浏览器自动弹出2345网址导航目录
可能问题五#xff1a;
问题分析#xff1a;
答案格式#xff1a;
shared_ptr的模拟实现
部分1#xff1a;引用计数的设计(分考点1)
代码实现#xff1a;
部分2#xff1a;作为类所必须的部分(分考点2)
代码实现#xff1a;
部分3#xff1a;拷贝构造函数…目录
可能问题五
问题分析
答案格式
shared_ptr的模拟实现
部分1引用计数的设计(分考点1)
代码实现
部分2作为类所必须的部分(分考点2)
代码实现
部分3拷贝构造函数(分考点3)
代码实现1
代码实现2
部分4模拟指针的行为(分考点4)
代码实现
部分5其他重要的成员函数(分考点5)
get()
use_count()
部分6定制删除器(分考点6)
代码实现1
代码实现2
shared_ptr自己模拟实现的最终答案展示
代码测试 我们接着进行智能指针的学习和试题研究。
可能问题五
模拟实现一下weak_ptr或者unique_ptr或者shared_ptr
问题分析
这个问题首先就明明是三个问题因为面试时间比较短不可能连续模拟实现三个智能指针的。所以依照重要性原则一般会重点实现shared_ptr由于全部实现起来比较多所以一般面试为了控制时间也会让你实现某个部分unique_ptr和weak_ptr也会讲的。有的同学可能会认为不会让你自我实现只需要懂得用就可以了但是如下图越是大厂的面试题可能或者一定是自我实现的部分(画蓝框的)的题还是相当多的 答案格式
这个问题放在了最后面说明是最难的确实呀实践类型的题目都挺难的但是只要知道逻辑和库里面的实现原理再加上面试的时候不紧张其实也没有那么难的。那么我们就先从最重要的shared_ptr讲起。
shared_ptr的模拟实现
我们先看看库里面是怎么写的做为一个类有什么成员函数和成员。 用红色框框括起来的部分就是比较重要的成员函数也就是我们等下要实现的函数其实我们也不需要和库里面写的完全一样主打一个差不多就可以了大致逻辑对就行了因为库里面在实现shared_ptr的时候还要考虑和别的智能指针兼容的问题我们就不用考虑这么多了我们主打一个能通过面试官的考核就行。
我们发现shared_ptr是由很多的不同部分组成的所以我们就分部分进行解答正好分部分也是考点。
部分1引用计数的设计(分考点1)
引用计数_count是设计在类里面的成员变量但是作为一个类里面的成员变量可以有多种设计方式可以是静态成员变量普通的成员变量或者new开辟的在堆里面的动态成员变量到底选择哪一种呢我们可以做如下分析 画图表示更直观
使用普通的成员变量 使用静态成员变量 我们会发现如果使用的是普通的开辟在栈里面的成员变量或者静态的全局变量都是跟着智能指针走的但是我们的引用计数计数的是一个空间被多少个智能指针管理着所以这个计数是肯定要跟着被管理的空间走的以上两种表示方法在本质上就理解错了追寻一个空间对应一个引用计数可知这个引用计数得另开辟一个空间管理并且一个空间才开辟一个也就是说只要遇到需要管理新空间时才新开辟智能指针。
那既然要新开辟空间就意味着这个引用计数本质上就是一个指针指向一个带开辟的空间。 代码实现
int* _count;
部分2作为类所必须的部分(分考点2)
这里主要是实现构造函数和析构函数
如果需要调用构造函数说明遇到了一个新的空间需要管理这时也需要对引用计数进行开辟空间
由于需要管理资源管理的同时履行帮忙销毁的任务所以需要将指向的空间连同开辟的引用计数一起销毁了因为当一个资源需要销毁时其引用计数一定为0了。
代码实现
shared_ptr(T* ptr nullptr) :_ptr(ptr) ,_count(new int(1)) {}
void release() { if (--(*_count) 0) { delete _ptr; delete _count; _ptr nullptr; _count nullptr; } }
~shared_ptr() { release(); }
为什么析构函数要另起一个函数这个问题之后会解答构造函数这么写其实还是和库里有所不同的因为库里认为如果智能指针管理一个空的空间那引用计数为0我们这边并没有做这种情况的另加考虑而是笼统的都初始化为1了但是不影响我们的大逻辑是对的。
部分3拷贝构造函数(分考点3)
shared_ptr是支持拷贝的拷贝分为两种一种是管理别人正在管理的空间相当于构造。如下
代码实现1
shared_ptr(const shared_ptrT sp)//不需要传成员对象因为成员里面本来就有 :_ptr(sp._ptr) , _count(sp._count)//多个智能指针共同使用一个引用计数{ (*_count);//那个空间的相当于多了一个智能指针在管理了所以跟着的引用计数要加1}
这个还看不懂的自己反思一下
还有一种就是将当前管理的空间和别的空间进行互换相当于换一块空间管理不再管理当前空间了
代码如下
代码实现2
shared_ptrT operator(shared_ptrT sp) { if (_ptr ! sp._ptr)//不可以自己析构自己因为没有意义 { //~shared_ptr();//虽然可以但是不支持直接调用这就是为什么析构函数这么写的原因了 release();//在转换指向对象时需要先释放当前的指向对象也就是相当于要现处理当前对象的引用计数 _ptr sp._ptr; _count sp._count; (*_count); } return *this; }
部分4模拟指针的行为(分考点4)
这个之前都讲过了直接看代码实现吧。
代码实现
T operator*() { return *_ptr; }
T* operator-() { return _ptr; }
部分5其他重要的成员函数(分考点5)
由于库里面实现的函数有很多但是重要的比较核心的就那么几个
get()
这个函数的作用是得到并返回指向管理这个空间的智能指针及指向这个空间的指针这个函数有大用的我们在weak_ptr的实现里面会讲。
T* get() const//返回指向一个已被管理的空间的指针{ return _ptr; }
use_count()
这个函数的作用是返回一个空间被多少个智能指针所管理也就是返回智能指针指向的引用计数的大小。
int use_count() const { return *_count;//返回指向空间的引用计数的个数 }
部分6定制删除器(分考点6)
定制删除器是shared_ptr自我实现里面比较难的部分了如果面试官没问就不需要在模拟实现的时候直接体现出来还有一个原因就是写了很容易错其实部分1到部分5已经足以体现智能指针管理资源和模拟指针的行为的功能了这个仅作为加分项。
首先定制删除器肯定要设计成类模板参数进行传递的成员变量这样便于析构函数调用因为外面知道定制删除器的类型有点多且当其为lambda时类型未知主要是uuid不知道所以这么多的类型设计成模板参数来能够表达并兼容各自类型很有必要。所以构造函数很好写的如下
代码实现1
templateclass D shared_ptr(T* ptr, D del)//缺省值要从右边往左边给所以ptr不能给缺省值 :_ptr(ptr) ,_count(new int(1)) ,_del(del)//如果没有传定制删除器就会默认使用缺省值进行构造构造函数是这样的{}
其实就是多加一个模板参数而已看不懂了自己反思一下
好啦你既然加了一个模板参数且这个删除器del是设计成员变量那对于这么多个类型难道在成员对象那里也加入模板参数这个方法其实是可行但是这是unique_ptr的设计理念shared_ptr不支持将删除器弄成模板的样子就是不支持再传一个模板参数那怎么办要同时能处理这么多类型又要不使用模板参数这个问题其实可以简化成如果可以用一个东西同时封装多个类型的变量就可以解决这个问题了。我们之前C11学过的包装器function就好像有这个功能吧对这里定义删除器变量就用的包装器进行封装的
代码实现2
T* _ptr;//智能指针的内部相当于指针管理空间的int* _count;//引用计数functionvoid(T* _ptr) _del [](T* _ptr) {delete _ptr; };//由于删除器的类型很多并且库里面不支持再传一个模板参数 //所以只能使用包装器对象因为这样可以兼容很多类型 //给一个lambda样式的缺省值是因为有时候没有传删除器无法直接使用现成的初始化
有了定制删除器对管理空间进行析构的时候就直接调用定制删除器(function对象)就可以了不需要使用delete毕竟不是所有的类型都可以用delete进行销毁的。代码如下
void release() { if (--(*_count) 0) { //delete _ptr; _del(_ptr); delete _count; _ptr nullptr; _count nullptr; } }
那这样将部分1到部分6全部整合在一起就是完整的shared_ptr了。整体代码如下
shared_ptr自己模拟实现的最终答案展示
namespace bit { templateclass T class shared_ptr { public: shared_ptr(T* ptr nullptr) :_ptr(ptr) ,_count(new int(1)) {} templateclass D shared_ptr(T* ptr, D del) :_ptr(ptr) ,_count(new int(1)) ,_del(del) {} shared_ptr(const shared_ptrT sp) :_ptr(sp._ptr) , _count(sp._count) { (*_count); } void release() { if (--(*_count) 0) { _del(_ptr); delete _count; _ptr nullptr; _count nullptr; } } shared_ptrT operator(shared_ptrT sp) { if (_ptr ! sp._ptr) { release(); _ptr sp._ptr; _count sp._count; (*_count); } return *this; } T* get() const { return _ptr; } int use_count() const { return *_count; } T operator*() { return *_ptr; } T* operator-() { return _ptr; } ~shared_ptr() { release(); } private: T* _ptr; int* _count; functionvoid(T* _ptr) _del [](T* _ptr) {delete _ptr; }; };
代码测试
int main() { bit::shared_ptrDate sp1(new Date); bit::shared_ptrDate sp2(sp1); bit::shared_ptrDate sp3(new Date); // 自己给自己赋值 sp3 sp3; sp1 sp2; sp1 sp3; sp2 sp3; bit::shared_ptrFILE sp5(fopen(test.cpp, w), Fclose()); bit::shared_ptrint sp6((int*)malloc(40), [](int* ptr) { cout free: ptr endl; free(ptr); }); return 0; } 经过测试发现我们写的实现逻辑没有什么问题
其实你到面试的时候一问到模拟实现shared_ptr就最先想到是一个名为shared_ptr的类然后依照上面的部分1到5逐步回忆着其中的逻辑然后按顺序写出来我相信你一定可以完成的。 文章转载自: http://www.morning.qfzjn.cn.gov.cn.qfzjn.cn http://www.morning.nlbw.cn.gov.cn.nlbw.cn http://www.morning.kfysh.com.gov.cn.kfysh.com http://www.morning.qglqb.cn.gov.cn.qglqb.cn http://www.morning.tbknh.cn.gov.cn.tbknh.cn http://www.morning.bhpjc.cn.gov.cn.bhpjc.cn http://www.morning.lzzqz.cn.gov.cn.lzzqz.cn http://www.morning.bctr.cn.gov.cn.bctr.cn http://www.morning.tzzfy.cn.gov.cn.tzzfy.cn http://www.morning.wdply.cn.gov.cn.wdply.cn http://www.morning.kbkcl.cn.gov.cn.kbkcl.cn http://www.morning.ksggr.cn.gov.cn.ksggr.cn http://www.morning.fnxzk.cn.gov.cn.fnxzk.cn http://www.morning.nrmyj.cn.gov.cn.nrmyj.cn http://www.morning.aowuu.com.gov.cn.aowuu.com http://www.morning.hgcz.cn.gov.cn.hgcz.cn http://www.morning.jnptt.cn.gov.cn.jnptt.cn http://www.morning.rlfr.cn.gov.cn.rlfr.cn http://www.morning.khcpx.cn.gov.cn.khcpx.cn http://www.morning.qtnmp.cn.gov.cn.qtnmp.cn http://www.morning.mlfmj.cn.gov.cn.mlfmj.cn http://www.morning.tzkrh.cn.gov.cn.tzkrh.cn http://www.morning.chgmm.cn.gov.cn.chgmm.cn http://www.morning.bytgy.com.gov.cn.bytgy.com http://www.morning.ylklr.cn.gov.cn.ylklr.cn http://www.morning.cthrb.cn.gov.cn.cthrb.cn http://www.morning.zhqfn.cn.gov.cn.zhqfn.cn http://www.morning.drfcj.cn.gov.cn.drfcj.cn http://www.morning.dtrz.cn.gov.cn.dtrz.cn http://www.morning.rjjjk.cn.gov.cn.rjjjk.cn http://www.morning.ldfcb.cn.gov.cn.ldfcb.cn http://www.morning.dnphd.cn.gov.cn.dnphd.cn http://www.morning.xlwpz.cn.gov.cn.xlwpz.cn http://www.morning.bnrff.cn.gov.cn.bnrff.cn http://www.morning.vuref.cn.gov.cn.vuref.cn http://www.morning.kysport1102.cn.gov.cn.kysport1102.cn http://www.morning.gnbfj.cn.gov.cn.gnbfj.cn http://www.morning.qhvah.cn.gov.cn.qhvah.cn http://www.morning.hhmfp.cn.gov.cn.hhmfp.cn http://www.morning.gmwqd.cn.gov.cn.gmwqd.cn http://www.morning.jmllh.cn.gov.cn.jmllh.cn http://www.morning.mbzlg.cn.gov.cn.mbzlg.cn http://www.morning.lsqmb.cn.gov.cn.lsqmb.cn http://www.morning.nbnq.cn.gov.cn.nbnq.cn http://www.morning.qmqgx.cn.gov.cn.qmqgx.cn http://www.morning.ktmnq.cn.gov.cn.ktmnq.cn http://www.morning.yfcyh.cn.gov.cn.yfcyh.cn http://www.morning.dmlsk.cn.gov.cn.dmlsk.cn http://www.morning.lnrr.cn.gov.cn.lnrr.cn http://www.morning.dnydy.cn.gov.cn.dnydy.cn http://www.morning.hlfgm.cn.gov.cn.hlfgm.cn http://www.morning.ybnzn.cn.gov.cn.ybnzn.cn http://www.morning.zwgbz.cn.gov.cn.zwgbz.cn http://www.morning.dpqqg.cn.gov.cn.dpqqg.cn http://www.morning.wmqxt.cn.gov.cn.wmqxt.cn http://www.morning.mwns.cn.gov.cn.mwns.cn http://www.morning.rcjwl.cn.gov.cn.rcjwl.cn http://www.morning.rbkdg.cn.gov.cn.rbkdg.cn http://www.morning.wgqtt.cn.gov.cn.wgqtt.cn http://www.morning.fgwzl.cn.gov.cn.fgwzl.cn http://www.morning.ymqfx.cn.gov.cn.ymqfx.cn http://www.morning.nkkr.cn.gov.cn.nkkr.cn http://www.morning.smmby.cn.gov.cn.smmby.cn http://www.morning.llthz.cn.gov.cn.llthz.cn http://www.morning.pkdng.cn.gov.cn.pkdng.cn http://www.morning.wmfmj.cn.gov.cn.wmfmj.cn http://www.morning.dfojgo.cn.gov.cn.dfojgo.cn http://www.morning.qczpf.cn.gov.cn.qczpf.cn http://www.morning.qzxb.cn.gov.cn.qzxb.cn http://www.morning.wxfjx.cn.gov.cn.wxfjx.cn http://www.morning.yodajy.cn.gov.cn.yodajy.cn http://www.morning.ddqdl.cn.gov.cn.ddqdl.cn http://www.morning.nrftd.cn.gov.cn.nrftd.cn http://www.morning.mwpcp.cn.gov.cn.mwpcp.cn http://www.morning.nfmtl.cn.gov.cn.nfmtl.cn http://www.morning.rjyd.cn.gov.cn.rjyd.cn http://www.morning.xpmwt.cn.gov.cn.xpmwt.cn http://www.morning.bpmdh.cn.gov.cn.bpmdh.cn http://www.morning.slzkq.cn.gov.cn.slzkq.cn http://www.morning.lizimc.com.gov.cn.lizimc.com