1. shared_ptr的使用方法
           ① 使用 “make_shared<类型>(初始化指向的对象)“ 生成智能指针
#include <iostream>
#include <memory>
#include <string>using namespace std;int main()
{shared_ptr<string>pstring = make_shared<string>("Hello"); // ()内部初始化方式为<类型>的初始化模式shared_ptr<string>pstring = make_shared<string>(10, 'p'); // ← 意义同上cout<<*pstring;// 使用  * 可以对指针进行解引用return 0;
}

②方便起见可以使用auto来进行对智能指针的类型声明

#include <iostream>
#include <memory>
#include <string>using namespace std;int main()
{auto pstring = make_shared<string>(10, 'p');cout << *pstring;return 0;
}

③shared_ptr的赋值与引用计数

#include <iostream>
#include <memory>
#include <string>using namespace std;int main()
{auto pstring = make_shared<string>(10, 'p');auto q = pstring;auto r = pstring;cout << pstring.use_count(); // use_count()这时的值为3{auto q = pstring;auto r = pstring;cout << pstring.use_count(); // use_count()这时的值为5} // 离开局部作用域会导致,局部作用域内部的智能指针被销毁cout << pstring.use_count(); // use_count()这时的值为3return 0;
}

④Str_Blob类

#include<vector>
#include<memory>
#include<iostream>
#include<initializer_list>
#include<list>using namespace std;class StrBlob
{public:typedef vector<string>::size_type size_type;StrBlob();StrBlob(initializer_list<string> il);size_type size() const{return data->size();}bool empty() const{return data->empty();}// 添加和删除元素void push_back(const string& t){data->push_back(t);}void pop_back();// 元素访问string& front();string& back();string& front()const;string& back()const;
private:shared_ptr<vector<string>> data;void check(size_type i, const string& msg) const;
};StrBlob::StrBlob() : data(make_shared<vector<string>>())
{}StrBlob::StrBlob(initializer_list<string>li) :data(make_shared<vector<string>>(li))
{}void StrBlob::check(size_type i, const string& msg)const
{if (i >= data->size()){throw out_of_range(msg);}
}string& StrBlob::front()
{check(0, "front on empty StrBlob");return data->front();
}string& StrBlob::back()
{check(0, "back on empty StrBlob");return data->back();
}string& StrBlob::front()const
{check(0, "front on empty StrBlob");return data->front();
}string& StrBlob::back()const
{check(0, "back on empty StrBlob");return data->back();
}void StrBlob::pop_back()
{check(0, "pop back on empty StrBlob");data->pop_back();
}int main()
{StrBlob b1;{StrBlob b2 = { "a", "an", "the" };b1 = b2;b2.push_back("about");cout << b1.size() << " " << b2.size() << endl;;}cout << b1.size(); // 这里的b1并没有被直接随着b2的销毁而销毁return 0;
}

⑤shared_ptr与new结合使用(不可以使用由new创建的指针来隐式转换智能指针)

#include<iostream>using namespace std;shared_ptr<int> clone(int p)
{// 这里采用了初始化的方式来使用普通指针初始化智能指针return shared_ptr<int>(new int(p)); // 这里涉及面向返回值类型的隐式转换 |  返回值必须要将普通指针绑定到智能指针上
}int main()
{int p = 100;shared_ptr<int>pointer = clone(p);*pointer += 1;cout << *pointer;return 0;
}

⑥unique_ptr的初始化与赋值

#include<iostream>using namespace std;int main()
{unique_ptr<int>p(new int(42));cout << *p << endl;unique_ptr<int>q;//q = p;//这种行为被禁止,不允许p在释放前赋值//q = p.release(); // 不允许赋值q.reset(p.release()); //将unique_ptr的控制权转让,重置q绑定的内存cout << *q << endl;// cout << *p << endl;  // 会发生堆栈异常 *p已经被释放return 0;
}

⑦可以拷贝将亡的unique_ptr以及unique_ptr的局部对象

#include<iostream>using namespace std;unique_ptr<int> clone_1(int p)
{return unique_ptr<int>(new int(p)); //拷贝将亡值
}unique_ptr<int> clone_2(int p)
{unique_ptr<int>ret = unique_ptr<int>(new int(p)); //可以拷贝将返回的局部对象return ret;
}int main()
{int p = 10;unique_ptr<int> c1(clone_1(p));unique_ptr<int> c2(clone_2(p));cout << *c1 << "\n" << *c2 << endl;return 0;
}

⑧ 习题 12.19

#include<iostream>
#include<vector>
#include<initializer_list>
#include<memory>
#include<string>
#include<stdexcept>using namespace std;class StrBlobPtr;class StrBlob
{friend class StrBlobPtr;
public:typedef vector<string>::size_type size_type;StrBlob() : data(make_shared<vector<string>>()){}StrBlob(initializer_list<string> il):data(make_shared < vector<string>>(il)){}size_type size() const{return data->size();}bool empty()const{return data->empty();}// 添加和删除元素void push_back(const string& t){data->push_back(t);}void pop_back(){check(0, "pop back on empty StrBlob");data->pop_back();}// 元素访问string& front(){// 如果vector为空check会抛出一个异常check(0, "front on empty StrBlob");return data->front();}const string& front()const{check(0, "front on empty StrBlob");return data->front();}string& back(){// 如果vector为空check会抛出一个异常check(0, "back on empty StrBlob");return data->back();}const string& back()const{check(0, "back on empty StrBlob");return data->back();}// 提供给 StrBlobPtr 的接口StrBlobPtr begin();StrBlobPtr end();
private:shared_ptr<vector<string>>data;void check(size_type i, const string& msg)const{if (i >= data->size()){throw out_of_range("msg");}}
};// 当试图访问一个不存在的元素的时候,StrBlob抛出一个异常
class StrBlobPtr
{friend bool eq(const StrBlobPtr&, const StrBlobPtr&);
public:StrBlobPtr() :curr(0){}StrBlobPtr(StrBlob& a, size_t sz = 0) :wptr(a.data), curr(sz){}string& deref()const{auto p = check(curr, "dereference past end");return (*p)[curr]; // 否则,返回指向vector的shared_ptr}StrBlobPtr& incr() // 前缀递增{check(curr, "increment past the end of StrBlobPtr");++curr;return *this;}StrBlobPtr& decr() // 前缀递减{--curr;check(-1, "decrement past the begin of StrBlobPtr");return *this;}
private:shared_ptr<vector<string>>check(size_t i, const string& msg) const{auto ret = wptr.lock();if (!ret){throw runtime_error("unbound StrBlobPtr");}if (i >= ret->size()){throw out_of_range(msg);}return ret; // 否则,返回指向vector的shared_ptr}weak_ptr<vector<string>>wptr;size_t curr;    // 在数组中的当前位置
};inline bool eq(const StrBlobPtr& lhs, const StrBlobPtr& rhs)
{auto l = lhs.wptr.lock(), r = rhs.wptr.lock();// 若底层的vector是同一个if (l == r){// 则两个指针都指向空,或者指向相同元素的时候,它们相等return (!l || lhs.curr == rhs.curr);}else{return false; // 若指向不同的vector则不可能相等}
}inline bool neq(const StrBlobPtr& lhs, const StrBlobPtr& rhs)
{return !eq(lhs, rhs);
}inline StrBlobPtr StrBlob::begin()
{return StrBlobPtr(*this);
}
inline StrBlobPtr StrBlob::end()
{auto ret = StrBlobPtr(*this, data->size());return ret;
}int main()
{StrBlob b1;{StrBlob b2 = { "a","an","the" };b1 = b2;b2.push_back("about");cout << b2.size() << endl;}cout << b1.size() << endl;cout << b1.front() << " " << b1.back() << endl;const StrBlob b3 = b1;cout << b3.front() << " " << b3.back() << endl;for (auto it = b1.begin(); neq(it, b1.end()); it.incr()){cout << it.deref() << endl;}return 0;
}

⑨ unique_Ptr自动管理动态数组

#include<iostream>using namespace std;int main()
{unique_ptr<int[]>up(new int[10]); // 定义指向10个元素的数组指针up.release(); // 销毁刚刚定义过的指针//为数组中的元素赋值for (int i = 0; i < 10; i++){up[i] = i;}return 0;
}

⑩ shared_Ptr手动管理动态数组

#include<iostream>using namespace std;int main()
{shared_ptr<int[]>sp(new int[10], [](int* p) {delete p; }); // 以lambda表达式的方式定义删除器
//  sp.reset(); // 使用自定义的删除器来执行智能指针指向数组的释放// 元素访问方式略有差别,shared_ptr不可以使用下标for (int i = 0; i < 10; i++){*(sp.get() + i) = i;}for (int i = 0; i < 10; i++){cout << sp[i] << "\t";}
}

11.allocator使用案例一

#include<iostream>using namespace std;int main()
{allocator<string>alloc;auto const p = alloc.allocate(100); // 分配100个未初始化的string对象string s;string* q = p; // q指向第一个stringwhile (cin >> s && q != p + 100){alloc.construct(q++, s); //用s初始化*q}const size_t size = q - p; // 记住读取了多少个string// 使用数组for (size_t i = 0; i < size; i++){cout << p[i] << "\t";}while (q != p) // 使用完毕释放已构造的string{alloc.destroy(--q);}alloc.deallocate(p, 100); // 释放内存return 0;
}

12.allocator使用案例二

#include<iostream>using namespace std;int main()
{allocator<int> alloc;auto const p = alloc.allocate(10);int* q = p;int count = 10;while (count--){int x;cin >> x;*q++ = x;}int size = q - p;for (int i = 0; i < size; i++){cout << p[i] << " ";}return 0;
}

005. C++智能指针相关推荐

  1. bartender一行打印两个二次开发_C++ 智能指针和二叉树:图解层序遍历和逐层打印二叉树...

    作者:apocelipes  链接:https://www.cnblogs.com/apocelipes/p/10758692.html 二叉树是极为常见的数据结构,关于如何遍历其中元素的文章更是数不 ...

  2. 五点讲述C++智能指针的点点滴滴

    (在学习C/C++或者想要学习C/C++可以加我们的学习交流QQ群:712263501群内有相关学习资料) 0.摘要 本文先讲了智能指针存在之前C++面临的窘境,并顺理成章地引出利用RAII技术封装普 ...

  3. 关于 智能指针 的线程安全问题

    先说结论,智能指针都是非线程安全的. 多线程调度智能指针 这里案例使用的是shared_ptr,其他的unique_ptr或者weak_ptr的结果都是类似的,如下多线程调度代码: #include ...

  4. C++ 智能指针(unique_ptr / shared_ptr)代码实现

    文章目录 unique_ptr 智能指针的实现 shared_ptr 智能指针的实现 指针类型转换 unique_ptr 智能指针的实现 一个对象只能被单个unique_ptr 所拥有. #inclu ...

  5. C++智能指针:unique_ptr详解

    文章目录 unique_ptr描述 声明 作用 函数指针描述 总结 unique_ptr描述 声明 头文件:<memory> 模版类: 默认类型template <class T, ...

  6. C++智能指针:weak_ptr实现详解

    文章目录 weak_ptr描述 声明 作用 原理实现 函数成员使用 总结 weak_ptr描述 声明 头文件:<memory> 模版类:template <class T> c ...

  7. C++智能指针: shared_ptr 实现详解

    文章目录 shared_ptr描述 声明 作用 原理实现 函数使用 关于shared_ptr循环引用问题 shared_ptr描述 声明 shared_ptr属于C++11特性中新加的一种智能指针,它 ...

  8. 【Smart_Point】C/C++ 中智能指针

    C++11智能指针 目录 C++11智能指针 1.1 C++11智能指针介绍 1.2 为什么要使用智能指针 1.2.1 auto_ptr(C++98的方案,C++11已经抛弃)采用所有权模式. 1.2 ...

  9. 【C++】智能指针(一)入门

    1. 智能指针背后的设计思想 智能指针背后的思想是RAII,参见博客[C++]零散知识 我们先来看一个简单的例子: void remodel(std::string & str) {std:: ...

最新文章

  1. js调整数组某些元素到指定位置顺序_Js数组里剔除指定的元素(不是指定的位置)...
  2. 7月新的开始 - Axure学习03 - 布尔运算、表单元件
  3. (38)编写 ShellCode
  4. 计算机科学软件工程专业大学排名,2020软件工程专业大学排名及录取分数汇总(2021理科生参考)...
  5. pytorch:ResNet50做新冠肺炎CT照片是否确诊分类
  6. FindBugs插件
  7. 剑指offer(7)斐波那契数列
  8. openstack镜像制作详解
  9. [kuangbin带你飞]专题九 连通图
  10. python监听键盘输入_Python监听鼠标键盘事件
  11. VM虚拟机,Linux系统安装tools过程遇到 what is the location of the “ifconfig” program
  12. 在OneNote中快速插入当前日期和时间
  13. 最大功率点跟踪测试软件,最大功率点跟踪(MPPT)
  14. 计算机内存条价格,最新内存条天梯图2020 内存条全面选购指南
  15. 陶博士-陶博士投资哲学-动量效应与反转效应
  16. 【BP-GA】基于GA的BP神经网络优化算法
  17. 金山打字通83字/分
  18. 10000php换人民币,转 数字转大写人民币
  19. 广播发送者广播接收者介绍
  20. 第三周 目标检测(Object detection)

热门文章

  1. 轻量级简约的自动采集小说程序源码
  2. 前段听一个仁兄说jbpm4 改变了很多
  3. 香草冰淇淋和代码调试
  4. aar打包依赖 android_打包依赖.aar文件以及坑总结
  5. linkerd 本地环境安装
  6. 申报须知,2022年滁州市各区县高新技术企业奖励政策变化,明光市
  7. 微信公众号怎样运营涨粉?
  8. 如何做一个企业网站制作
  9. 蓝桥杯2017国赛 瓷砖样式 dfs+map
  10. 计算机网络atm功能,计算机网络实用技术知识点之ATM原理