1,智能指针是啥?
普通指针基本上就是一个变量,它的的生命周期和变量的作用域有关,局部变量在走出作用域以后就会销毁,全局变量可能程序运行完了就销毁了。
new出来的指针和普通指针的区别在于,new出来的那块内存区域是不会自动被释放的,需要你手动调用delete才能释放,然而由于种种原因,new----delete这俩节奏总是出状况,于是有人想到了自动回收的指针
智能指针根本上是一个class,你可以生成一个class实例用以管理一块内存,内存中放上你想放的东西,一方面该实例记录着该内存的地址,类型等信息,你可以和普通指针似的使用它,另一方面它记录对该内存的引用,当引用为0,就把该指针指向的内存区域释放出来。
2,shared_ptr共享指针:
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;
}
原文链接: https://www.cnblogs.com/0-lingdu/p/12327136.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/195567
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!