智能指针——c++primer第五版12章——个人总结

来源:互联网 发布:知乎 核安全所 编辑:程序博客网 时间:2024/06/08 08:09
//#include "stdafx.h"#include <memory>#include <string>#include <vector>#include<new>using namespace std;//名字空间,不然使用的时候写std::shared_ptrint main(){//1:智能指针的定义与初始化;shared_ptr<int> pint1;//定义,不初始化就是一个空指针shared_ptr<int> pint2 = make_shared<int>();//默认初始化 int默认是0shared_ptr<int> pint3 = make_shared<int>(44);//值初始化shared_ptr<string> pstr1 = make_shared<string>(10, 'a');//用string的某一个重载构造函数初始化auto pVecString1 = make_shared<vector<string>>();//auto也可以//pint2 = new int(1024);pint2.reset(new int(1024));//让pint2指向一个新对象,计数器-1,如有必要,释放原内存,新计数器+1//2:shared_ptr与unique_ptr共有的操作int * pint4 = pint2.get();//get()将返回一个int*类型的指针,注意不能释放掉pint4所指向的空间,不然会使pint2失效swap(pint2, pint3);//或者pint2.swap(pint3);//交换两个指针//3:shared_ptr独有的操作make_shared<int>(5);//构造shared_ptr的函数,返回值是shared_ptr<int>bool isUnique = pint3.unique();//判断pint3是不是唯一指向这个对象的指针 这个例子中返回falseint useCount = pint3.use_count();//返回指向pint3指向对象的所有指针的个数 这个例子中返回1//4:直接管理内存string *ps1 = new string;//使用string的默认初始化构造函数string *ps2 = new string();//使用string的""值初始化函数,只不过这个值是空值。//我觉得上面这两句的概念不一样吧,但结果是一样的,都是空string。int *pi1 = new int;//默认初始化 pi1指向的值未定义,int的默认初始化不会为它赋值,string的默认初始化为自己赋值为空。int *pi2 = new int();//值初始化,pi2指向的值是0auto pin = new auto(5);//可以推测出pin的类型是int *const int *pci = new const int(1024);//动态分配的const必须初始化,const int *pci = new const int;是错误的const string *pcsi = new const string;//默认是空串 这是可以的int *p2 = new(nothrow)int;//相当于传递给new一个参数 如果内存没空间了 返回一个空指针,而不是报错 头文件#include<new>delete ps1;//释放内存,但ps1变成空悬指针,指向的地方没有东西。ps1 = nullptr;//重置指针为空,这是一种保护方式,//5.shared_ptr new 结合使用shared_ptr<double> pdou1(new double(10.8));//之后不用delete来释放内存,pdou1在作用域结束时会释放内存//注意shared_ptr<double> pdou1=new double(10.8);的写法是错误的,因为shared_ptr的构造函数是explicitif (!pstr1.unique())pstr1.reset(new string(*pstr1));*pstr1 += "hellpo";//上面这三行代码的含义是:pstr1是我上面定义的智能指针,假设现在我想通过这个智能指针改变所指向对象的值,//但是如果有其他智能指针也指向这个对象,那我就间接的把其他智能指针的对象也改变了,//因为这些智能指针所指都是同一个对象。所以,判断一下是否自己是唯一指针,如果不是唯一指针的话,//让pstr1重新指向一个拥有同一个对象值的string,相当于又开辟了一块内存。再改变新的对象.//6.智能指针与异常//如果在我写的这整段程序的这一位置出现了异常,那么最后的return0和}不会执行,即使这样,shared_ptr所指的内存也能自动释放,//但是new出来的内存,没碰到delete就不能被释放. 优点:使用智能指针可以避免内存泄漏!//7.unique_ptr 指向唯一的对象 不能拷贝 unique_ptr<int> unPin1(p2);是错误的 不能赋值 unPin1=p2也是错误的unique_ptr<int> unPin1(new int(48));//unique_ptr<T,D> un(d);指向T对象,用类型为D的对象d来代替delete//unPin1 = nullptr;//释放对象 或者nuPin1.reset(nullptr);//unPin1.release();//返回原指针,同时原指针放弃对指针的控制权,并置空,但是这种写法是不正确的,因为内存不会释放!!!//unPin1.reset();//unPin1.reset(p);释放并指向内置指针p//用release 和 reset解决unique_ptr不能拷贝和赋值的情况,上面几行我注释掉,因为我要运行,不想让它变空unique_ptr<int> unPin2(new int(53));unique_ptr<int> unPin3(unPin2.release());//这样就可以拷贝了unPin1.reset(unPin3.release());//这样就可以赋值了int* unPin1copy = unPin1.release();//release一定要赋值 不然就没有释放内存 返回类型int*//8.weak_ptrauto p = make_shared<int>(76);weak_ptr<int> wp(p);//weak_ptr用shared_ptr来构造,不增加引用计数,不控制对象的生存期 “弱”wp = p;//支持赋值wp.reset();//指针置空wp.use_count();//返回这个对象shared_ptr的数量    wp.expired();//use_count为0时返回truewp.lock();//返回一个shared_ptr 可以是空 或者是指向某对象的//weak_ptr不能用来访问对象,一定是用lock()if(shared_ptr<int> np=wp.lock()){}return 0;}
#pragma once#include <memory>#include <string>#include <vector>#include<initializer_list>#include"StrBlobPtr.h"using namespace std;//不写名字空间的话 好麻烦 class StrBlob {public:typedef std::vector<std::string>::size_type size_type;StrBlob():data(std::make_shared<std::vector<std::string>>()){}StrBlob(std::initializer_list<std::string> &l):data(std::make_shared<std::vector<std::string>>(l)){}size_type size()const { return data->size(); }bool empty()const { return data->empty(); }void push_back(std::string &s) { data->push_back(s); }void pop_back(){check(0, "popback on empty StrBlob");data->pop_back();}std::string &front() { check(0, "front on empty StrBlob");return (*data)[0]; }std::string &back() { check(0, "back on empty StrBlob");return (*data)[data->size() - 1]; }const string &front()const{}//重载const类型const string &back()const{}//同上friend class StrBlobPtr;StrBlobPtr begin() {return StrBlobPtr(*this);}StrBlobPtr end() {StrBlobPtr p = StrBlobPtr(*this, data->size());return p;}private:std::shared_ptr<std::vector<std::string>> data;void check(size_type i,const std::string &msg)const{    //检查元素是否存在 if (i >= data->size())throw out_of_range(msg);}};
#pragma once#include <memory>#include <string>#include <vector>#include<initializer_list>using namespace std;class StrBlobPtr {public:StrBlobPtr():cur(0){}StrBlobPtr(StrBlob &rhs,size_t sz=0):wptr(rhs.data),cur(sz){}private:weak_ptr<vector<string> > wptr;size_t cur;shared_ptr<vector<string>> check(size_t i, const string &msg){    //check函数返回一个智能指针 如果不存在 回抛出异常auto p = wptr.lock();if (!p)throw runtime_error("unbound");if (i >= p->size())throw out_of_range("msg");return p;}};



阅读全文
0 0