标签:print 决定 注意 string div 区域 get 获取数据 操作符
普通指针基本上就是一个变量,它的的生命周期和变量的作用域有关,局部变量在走出作用域以后就会销毁,全局变量可能程序运行完了就销毁了。
new出来的指针和普通指针的区别在于,new出来的那块内存区域是不会自动被释放的,需要你手动调用delete才能释放,然而由于种种原因,new----delete这俩节奏总是出状况,于是有人想到了自动回收的指针
智能指针根本上是一个class,你可以生成一个class实例用以管理一块内存,内存中放上你想放的东西,一方面该实例记录着该内存的地址,类型等信息,你可以和普通指针似的使用它,另一方面它记录对该内存的引用,当引用为0,就把该指针指向的内存区域释放出来。
1),基本语法
#include <stdarg.h> #include <iostream> #include <string> #include <memory> //shared_ptr using namespace std; int main(void) { /*使用传入参数的方法生成智能指针*/ shared_ptr<int> p1(new int); //创建一个int型的智能指针对象:在堆上创建两块内存,一个用于存储int,另一个用于记录对刚刚那块内存的引用的数量,初始化引用数量为1. //语法含义:shared_ptr是个模板类,使这个模板类按照int类型生成class类,然后创建p1对象,并且传递参数:new int,new int的意思是申请一个int大小的内存块,并且返回该内存块的地址。 cout << p1.use_count() << endl; //检查p1所指向的内存块的引用计数,当前为1 shared_ptr<int> p2 = p1; //创建新的智能指针p2也指p1指向的内存,这样的写法也可以:shared_ptr<int> p(p1) cout << p1.use_count() << endl; //现在引用数目为2 p2.reset(); //取消p2的指向,带参数的话p2会建立指向新内存 cout << p1.use_count() << endl; //现在引用数目为1 p2 = nullptr; //把p2重置为nullptr(这大约是空指针约定俗成的写法,暂不讨论) if (p2 == nullptr) { printf("empty ptr\n"); } /*使用构造函数来创建智能指针,推荐使用这种方法*/ shared_ptr<int> p3 = std::make_shared<int>(); //语法含义:int型智能指针shared_ptr的类实例p1的地址是什么呢?是模板函数make_shared根据int类型生成的存值内存的地址,当然它还同时生成了存储引用的内存 //有人说使用智能指针存储数组会有问题,因为数组释放内存需要用delete [] ptr;而不是delete ptr;需要重写析构方法 //不清楚内部机制以及看不懂源码的我,最后决定不用智能指针存储数组,问题暂时放着吧 /*以下是错误示范,虽然也能跑*/ shared_ptr<int[10]> p4 = std::make_shared<int[10]>(); cout <<"array1:"<< p4.use_count() << endl; p4.reset(); cout <<"array2:"<< p4.use_count() << endl; return 0; }
2),如何从智能指针中获取数据?
#include <stdarg.h> #include <iostream> #include <string> #include <memory> //shared_ptr #include <vector> using namespace std; int main(void) { /*普通的vector的使用:*/ vector<int> hehe = { 4,5 }; vector<int> hehe1 = vector<int>(2,4); //生成一个内容是两个4的int的普通vector hehe1.push_back(4); //普通vector追加数据 for (auto itt : hehe1) { printf("orign:%d\n", itt); } /*智能指针指向的vector怎么用?*/ shared_ptr < vector<int > > vi0(new vector<int>); //声明一个智能指针指向int的vector vi0->push_back(1); vi0->push_back(2); //智能指针vector追加数据,1和2,注意操作符是这样的:-> for (auto itt : (*vi0)) { printf("shared_ptr:%d\n", itt); } //shared_ptr < vector<int > > vi = make_shared<vector<int >>(hehe); shared_ptr < vector<int > > vi = make_shared<vector<int >>(2,3); //使用构造函数声明并且初始化一个智能指针指向int的vector,内容是两个3 int len1 = (*vi).size(); int len2 = vi->size(); //两种方法获取vector长度,一个是使用*翻译智能指针,另一个是使用:-> printf("len1:%d,len2:%d\n",len1, len2); printf("use count1:%d\n", vi.use_count()); //智能指针本来只有一个引用 vector<int> *test = vi.get(); //据说是让智能指针返会一个普通指针, printf("use count2:%d\n", vi.use_count()); //看来get()方式并不能让智能指针引用增加,现在它还是只有一个引用 printf("address of test:%p\n", test); //vi销毁以前查看一下test地址 vi = nullptr; //智能指针销毁 printf("use count3:%d\n", vi.use_count()); //现在引用为0,确实销毁了 printf("address of test:%p\n", test); //销毁以后地址还是指向那块内存,test的地址没有改变 printf("len of test : %d\n", (*test).size()); //但是已经不能获取到长度,应该是已经没法使用或者地址上全都填充0了,返回0 *test= vector<int>(2, 4); //但是依旧可以在那块内存上进行操作,比如重新赋值 printf("len of test : %d\n", (*test).size()); //可以获取长度,2 for (auto itt : (*test)) { printf("test:%d\n", itt); } //可遍历 return 0; }
标签:print 决定 注意 string div 区域 get 获取数据 操作符
原文地址:https://www.cnblogs.com/0-lingdu/p/12327136.html