代码示例
用shared_ptr指向vector,利用智能指针管理vector比自己用智能指针申请数组好
#include <iostream>
#include<memory>
#include<vector>
#include<iostream>
using std::cout;
using std::endl;
using std::cin;
using std::shared_ptr;
using std::unique_ptr;
using std::auto_ptr;
using std::vector;
using std::make_shared;
shared_ptr<vector<int>> shared(int size=0) {
return make_shared<vector<int>>(size);//直接返回智能指针,引用计数返回后就是1
}
shared_ptr<vector<int>> use_shared() {
shared_ptr<vector<int>> ptr1 = shared();//执行完此行后ptr自动析构,其内存自动释放
cout << "目前有" << ptr1.use_count() << "个智能指针指向该动态对象" << endl;
if (ptr1.unique()) {
cout << "该指针是单身狗哦" << endl;
}
shared_ptr<vector<int>> ptr2 = ptr1;//右指针引用计数++,ptr2也是同类型的智能指针,所以又++,
cout << "目前有" << ptr1.use_count() << "个智能指针指向该动态对象" << endl;
return ptr2;//返回后,ptr2指针先完成返回值的赋值,然后ptr2,ptr1依次析构,引用计数减少2次
}
int main()
{
shared_ptr<vector<int>> ptr3 = use_shared();
cout << "目前有" << ptr3.use_count() << "个智能指针指向该动态对象" << endl;//所以这里计数为1
for(int i=0;i<10;i++)
ptr3->push_back(i);
for (auto i : *ptr3) {//重载*,能*ptr3和->访问元素和函数
cout << i << " ";
}
}
API调用说明
make_shared(args…) | 指定T类的args形参的构造函数,返回对象的指针 |
---|---|
shared_ptr(another_shared_ptr) | 拷贝一个shared_ptr,计数++ |
p=q | 递减p计数,递增q计数,若p计数递减为0,则自动释放其管理的对象内存 |
p.unique() | 若计数为1,则返回1,否则返回0 |
p.use_count() | 返回p管理对象一共有多少个shared_ptr指向它 |
p | 单纯一个shared_ptr可以作为判断空的条件 |
*p | 解引用指针,返回其指向的对象 |
p->member() | 调用member函数 |
p->data | 访问data数据 |
(*p).someMember | 解引用后访问 |
p.get() | 返回普通指针,慎用!! 千万不能用get去初始化一个智能指针 |
p.reset() | 释放p指向的对象 |
p.reset(q) | 让p指向q,并释放原来p指向的对象 |
p.reset(q,d) | 让p指向q,并释放原来p指向的对象,使用d作为删除器 |
shared_ptr的陷阱
void f(shared_ptr<int> p){}
int main(){
int* x=new int(1);
f(make_shared<int>(x));//计数为1后,shared_ptr析构后变为0,释放x指向的内存
int j=*x;//释放后又寻址,将出错!!!!
}
类中含有智能指针:
C++Primer对智能指针的计数描述:
给智能指针初始化则计数++
赋值shared_ptr会递增右侧而递减左侧指针计数
如果计数为0,则自动销毁该指针管理的对象
默认生成的复制构造函数,赋值运算符的情况下
A类中含有智能指针,则A类的拷贝,赋值,销毁也会导致智能指针的拷贝,赋值和销毁
shared_ptr不直接支持管理动态数组,如果要申请,则必须自己定义删除器
所以shared_ptr不支持指针的[]运算,和自增,自减运算
shared_ptr遍历数组方式:
shared_ptr<int> sp(new int[10],[](int*p){delete[] p;}
for(int i=0;i<10;i++)
cout << *(sp.get()+i) << " " ;
如果shared_ptr管理的不是new出来的资源,那么记得给他传递一个删除器来管理你的资源