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

国外字体设计网站湖南营销网站建设

国外字体设计网站,湖南营销网站建设,网站建设定制公司推荐,健康管理咨询公司文章目录 简介源码解析1. 引用计数的实现方式2. deleter静态方法的赋值时间节点3.make_smart的实现方式 与 好处4. 几种构造函数4.1 空构造函数4.2 接收指针的构造函数4.3 接收指针和删除方法的构造函数 , 以及auto进行模板lambda的编写4.4 拷贝构造函数4.5 赋值运算符 5. rele… 文章目录 简介源码解析1. 引用计数的实现方式2. deleter静态方法的赋值时间节点3.make_smart的实现方式 与 好处4. 几种构造函数4.1 空构造函数4.2 接收指针的构造函数4.3 接收指针和删除方法的构造函数 , 以及auto进行模板lambda的编写4.4 拷贝构造函数4.5 赋值运算符 5. release函数, 指针的delete 和 设置为nullptr6. 获取内部变量, 指针和引用 简介 git地址: shimachao/smart_ptr说明: 这是一个仿写shared_ptr的库, 只有简短的200行, 实现了shared_ptr的大部分功能, 上手简单, 非常适合新手阅读.本文说明: 由于本项目没有那么多难点, 就不再像上篇开源代码阅读中c源码阅读__ThreadPool__正文阅读一样, 不单独开一个前提知识部分了, 由于本项目比较简单, 大家就当作对shared_ptr的一次复习. 看一乐呵就行. 源码 此代码在c20环境下直接可以运行, 源码如下 #pragma once#include functional// 模仿shared_ptr实现一个智能指针 template typename T class smart_ptr { public:smart_ptr();explicit smart_ptr(T*);smart_ptr(const smart_ptr);smart_ptr(T*, std::functionvoid(T*));smart_ptr operator(const smart_ptr);T operator*() const;T* operator-() const;~smart_ptr();// 向bool的类型转换explicit operator bool() const;bool unique();void reset();void reset(T*);void reset(T*, std::functionvoid(T*));T* release();T* get() const;private:// 默认的deleterstatic std::functionvoid(T*) default_del;private:unsigned* m_p_use_count nullptr;T* m_pobject nullptr;std::functionvoid(T*) m_del default_del; };template typename T std::functionvoid(T*) smart_ptrT::default_del [](T*p) {delete p; p nullptr; };template typename T, typename... Args smart_ptrT make_smart(Args... args) {smart_ptrT sp(new T(std::forwardArgs(args)...));return sp; }template typename T smart_ptrT::smart_ptr():m_pobject(nullptr), m_p_use_count(new unsigned(1)) { }template typename T smart_ptrT::smart_ptr(T *p):m_pobject(p), m_p_use_count(new unsigned(1)) { }template typename T smart_ptrT::smart_ptr(T *p, std::functionvoid(T*) del):m_pobject(p), m_p_use_count(new unsigned(1)), m_del(del) { }template typename T smart_ptrT::smart_ptr(const smart_ptr rhs):m_pobject(rhs.m_pobject), m_p_use_count(rhs.m_p_use_count), m_del(rhs.m_del) {(*m_p_use_count); }template typename T smart_ptrT smart_ptrT::operator (const smart_ptr rhs) {// 使用rhs的deleterm_del rhs.m_del;// 递增右侧运算对象的引用计数(*rhs.m_p_use_count);// 递减本对象的引用计数if (--(*m_p_use_count) 0){// 如果管理的对象没有其他用户了则释放对象分配的成员m_del(m_pobject);delete m_p_use_count;}m_p_use_count rhs.m_p_use_count;m_pobject rhs.m_pobject;return *this; // 返回本对象 }template typename T T smart_ptrT::operator*() const {return *m_pobject; }template typename T T* smart_ptrT::operator-() const {return this-operator*(); }template typename T smart_ptrT::~smart_ptr() {if (--(*m_p_use_count) 0){m_del(m_pobject);m_pobject nullptr;delete m_p_use_count;m_p_use_count nullptr;} }template typename T bool smart_ptrT::unique() {return *m_p_use_count 1; }template typename T void smart_ptrT::reset() {(*m_p_use_count)--;if (*m_p_use_count 0){m_del(m_pobject);}m_pobject nullptr;*m_p_use_count 1;m_del default_del; }template typename T void smart_ptrT::reset(T* p) {(*m_p_use_count)--;if (*m_p_use_count 0){m_del(m_pobject);}m_pobject p;*m_p_use_count 1;m_del default_del; }template typename T void smart_ptrT::reset(T *p, std::functionvoid(T*) del) {reset(p);m_del del; }template typename T T* smart_ptrT::release() {(*m_p_use_count)--;if (*m_p_use_count 0){*m_p_use_count 1;}auto p m_pobject;m_pobject nullptr;return p; }template typename T T* smart_ptrT::get() const {return m_pobject; }template typename T smart_ptrT::operator bool() const {return m_pobject ! nullptr; }解析 这里会把smart_ptr类中每一部分都单独拿出来说明, 并进行举例 1. 引用计数的实现方式 我们可以看到他的实现方式 unsigned* m_p_use_count nullptr;使用的是整数的指针, 如果不使用指针的话, 那么是打不到公用引用计数的效果的, 如下 int* a1 new int(1); int* a2 a1; *a2 1; cout *a1 endl; cout *a2 endl;int a3 1; int a4 a3; a3 1; cout a4 endl; cout a4 endl;int a5 1; int a6 a5; a5; cout a5 endl; cout a6 endl;执行结果 那么我们是不是也可以用引用来实现引用计数的共用呢? 我觉得是可以的 2. deleter静态方法的赋值时间节点 template typename T class smart_ptr { private:// 默认的deleterstatic std::functionvoid(T*) default_del;std::functionvoid(T*) m_del default_del; } template typename T std::functionvoid(T*) smart_ptrT::default_del [](T*p) {delete p; p nullptr; };静态方法的赋值, 是 程序启动并进入主函数之前进行赋值的, 具体地这个初始化是在包含这行代码的翻译单元被加载时完成的, 所以 default_del在任何smart_ptr的构造函数调用之前就赋值了. m_del的赋值是在smart_ptr的构造函数被调用时赋值的 3.make_smart的实现方式 与 好处 template typename T, typename... Args smart_ptrT make_smart(Args... args) {smart_ptrT sp(new T(std::forwardArgs(args)...));return sp; }这里右值引用和完美转发相关的知识在左值右值, 左值引用右值引用,完美转发这篇博客中有详细介绍. 这里和shared_ptr一样, 也是接收目标类的构造函数的参数, 直接返回智能指针的实现方式 好处: 我们使用make_smart的方式, 创建智能指针非常好, 因为不用我们手动new一个指针出来, 那么智能指针外部就没有该指针的变量, 就不会造成一些未知错误, 保证了在指针的生命周期内, 都是被智能指针安全管理的. 4. 几种构造函数 常用的构造函数和赋值运算符 在这篇文章里有介绍 C基础知识对象移动拷贝构造函数移动拷贝构造函数赋值运算符移动赋值运算符 4.1 空构造函数 template typename T smart_ptrT::smart_ptr():m_pobject(nullptr), m_p_use_count(new unsigned(1)) {}这个方法是构造一个内容为空的智能指针, 声明方式如下 smart_prtMyClass sp(); 这个可以配合后面的reset方法使用, 给智能指针重新赋值 4.2 接收指针的构造函数 template typename T smart_ptrT::smart_ptr(T *p):m_pobject(p), m_p_use_count(new unsigned(1)) {}使用方式如下, 但是不推荐这种方式, 因为外部有了指针变量s1, 这就给智能指针的管理带来了未知的风险 MyStruct* s1 new MyStruct(1, 2); smart_ptrMyStruct sp(s1);4.3 接收指针和删除方法的构造函数 , 以及auto进行模板lambda的编写 template typename T smart_ptrT::smart_ptr(T *p, std::functionvoid(T*) del):m_pobject(p), m_p_use_count(new unsigned(1)), m_del(del) {}这个构造方法就是上面4.2多加一个参数, 没什么好说的, 但是其中delete方法的传入, 我们可以通过auto来编写模板lambda, 这是c新的特性, 如下 auto deleter [](auto* p) {delete *p; p nullptr;}; MyStruct* s new MyStruct(1, 2); smart_ptrMyStruct sp(s, deleter);这样, 我们就不用template写一大堆, 而直接构造出了一个模板函数 4.4 拷贝构造函数 拷贝构造函数, 会造成引用计数1, 两个智能指针指向的是同一块地址 template typename T smart_ptrT::smart_ptr(const smart_ptr rhs) :m_pobject(rhs.m_pobject), m_p_use_count(rhs.m_p_use_count), m_del(rhs.m_del) {(*m_p_use_count); }符号的赋值, 是赋值的内容, 不是变量本身的地址设置为一致(这是引用的), 所以指针的, 是指针变量内指向的地址设置为相同 MyStruct* s1 new MyStruct(1, 2); smart_ptrMyStruct sp(s1); smart_ptrMyStruct sp2(sp); cout std::boolalpha; cout (sp.get() sp2.get()) endl;执行结果 4.5 赋值运算符 赋值运算符 和 拷贝构造函数就大不一样了, 赋值运算符会把等号左边的智能指针内的变量引用计数-1, 如果引用计数为0了, 还会释放资源 template typename T smart_ptrT smart_ptrT::operator (const smart_ptr rhs) {// 使用rhs的deleterm_del rhs.m_del;// 递增右侧运算对象的引用计数(*rhs.m_p_use_count);// 递减本对象的引用计数if (--(*m_p_use_count) 0){// 如果管理的对象没有其他用户了则释放对象分配的成员m_del(m_pobject);delete m_p_use_count;}m_p_use_count rhs.m_p_use_count;m_pobject rhs.m_pobject;return *this; // 返回本对象 }所以根据代码, 我们合理预测, 如果左边的智能指针引用计数如果是1的话, 那么使用了赋值运算符, 就会造成内部的指针析构 测试代码 struct MyStruct {MyStruct() default;MyStruct(int a, int b) :a(a), b(b) {}~MyStruct() { cout ~MyStruct ( a , b ) endl;}int a;int b; };int main() {smart_ptrMyStruct sp1 make_smartMyStruct(1, 2);smart_ptrMyStruct sp2 make_smartMyStruct(3, 4);sp1 sp2;cout endl;return 0; }执行结果 可以看到, 是sp1在程序结束之前析构的 5. release函数, 指针的delete 和 设置为nullptr 这里我们要明确,delete是把指针指向的内容进行析构, 而直接把指针设置为nullptr, 只是把当前这个指针变量设置为nullptr, 对于指针指向的内容, 不做任何处理 比如release函数 template typename T T* smart_ptrT::release() {(*m_p_use_count)--;if (*m_p_use_count 0){*m_p_use_count 1;}auto p m_pobject;m_pobject nullptr;return p; }在这个函数里, 只是把m_pojbect这个指针变量本身设置为了nullptr, 而指针指向的变量没有做任何操作, 最后把这个指针变量copy一份, 返回出去了 测试代码 struct MyStruct {MyStruct() default;MyStruct(int a, int b) :a(a), b(b) {}~MyStruct() { cout ~MyStruct ( a , b ) endl;}int a;int b; };int main() {smart_ptrMyStruct sp1 make_smartMyStruct(1, 2);MyStruct* s1 sp1.release();cout endl;delete s1;return 0; }执行结果 可以看到, release确实没有造成析构 6. 获取内部变量, 指针和引用 有两个方法, 一个是重载的操作符*, 一个是get方法 只不过get获取的指针 *获取的是引用 template typename T T smart_ptrT::operator*() const {return *m_pobject; } template typename T T* smart_ptrT::get() const {return m_pobject; }测试代码 int main() {smart_ptrMyStruct sp1 make_smartMyStruct(1, 2);cout std::boolalpha endl;// (*sp1)获取了引用: MyStruct, 转为指针 *(MyStruct)cout ((*sp1) sp1.get()) endl;return 0; }执行结果
http://www.w-s-a.com/news/437836/

相关文章:

  • 梧州外贸网站推广设计wordpress 上传 七牛
  • 增加网站备案千灯做网站
  • 深圳做网站的公php做简易网站
  • 徐州哪家做网站好商业空间设计效果图
  • 重庆建网站cqiezscom大学毕业做网站插画师好吗
  • 在门户网站做产品seo怎么样做网站管理员
  • 动画做视频在线观看网站字体安装+wordpress
  • vs2015网站开发做珠宝建个网站推广怎么样
  • 大桥外语官方网站星做宝贝佛山微信网站开发
  • 河南建设网站公司哪家好怎样做一家网站
  • 安阳市哪里做网站建设网站流量怎么赚钱
  • 网站开发与优化课程总结软件班级网站建设
  • py网站开发wordpress 公司网站 模板 下载
  • 长春城乡建设部网站首页英文网站推广服务
  • wordpress实训上海整站seo
  • 福建自己建设网站义乌市企推网络科技有限公司
  • 宁波优化网站哪家好织梦网站地图怎么做
  • 怎么在自己的网站加关键词烟台企业网站建设
  • 中山网站建设界面设计职业技能等级证书
  • 做网站首页多少钱免费版企业邮箱注册
  • ppp模式在网站建设的南昌专业做网站公司哪家好
  • 泰安网站建设制作电话号码百度sem竞价托管公司
  • 苏网站建设网页设计和网页美工
  • 跨境电商平台网站广州地铁站路线图
  • 吉林省交通建设集团有限公司网站企业网站推广的策略有哪些
  • 网站内链怎么做更好郑州网站建设哪家便宜
  • 建设大型购物网站运城哪里做网站
  • php企业网站通讯录管理系统做网站在线支付系统多少钱?
  • 怎么区分用vs和dw做的网站贝贝网网站开发背景
  • 无锡网站建设制作建设信息网查询