1. 智能指针分3类:今天只唠唠shared_ptr
- shared_ptr
- unique_ptr
- weak_ptr
2. 下表是shared_ptr和unique_ptr都支持的操作
操作 | 功能描述 |
---|---|
shared_ptr<T> sp | 空智能指针,可以指向类型为T的对象 |
unique_ptr<T> up | 空智能指针,可以指向类型为T的对象 |
p | 将p用作一个条件判断,如果p指向一个对象,则为true |
*p | 解引用p,获得它指向的对象 |
p->mem | 等价于(*p).mem,访问p所指对象的mem成员 |
p.get() | 返回p中保存的指针。如果指向的对象已经被释放,就是一个危险的指针 |
swap(p, q)或者p.swap(q) | 交换p和q中的指针 |
上面操作的验证代码
#include <memory>
#include <iostream>
#include <vector>
using namespace std;
class Test{
public:
Test(int d = 0):data(d){cout << "cr:" << data << endl;}
~Test(){cout << "fr:" << data << endl;}
void fun(){
cout << "Test func(" << data << ")" << endl;
}
private:
int data;
};
int main(){
//shared_ptr<Test> sp = make_shared<Test>();
Test* pt = new Test();
shared_ptr<Test> sp(pt);
if(sp){
cout << "sp指向了对象" << endl;
}
(*sp).fun();
shared_ptr<int> isp;
if(!isp){
cout << "isp没有指向对象" << endl;
}
Test* tmp1 = sp.get();
auto sp1 = make_shared<Test>(10);
Test* tmp2 = sp1.get();
swap(sp, sp1);
tmp1->fun();//0
tmp2->fun();//10
//sp和sp1所指向的对象被交换了
sp.get()->fun();//10
sp1.get()->fun();//0
}
3. 下表是shared_ptr独有的操作
操作 | 功能描述 |
---|---|
make_shared<T>(args) | 返回shared_ptr,指向一个动态分配的类型为T的对象。使用args初始化此对象。 |
shared_ptr p(q) | p是q的拷贝;递增q中的计数器。q中的指针必须能转化成T*。 |
p = q | p和q都是shared_ptr,所保存的指针必须能相互转换。递减p的引用计数;递增q的引用计数;如果p的引用计数变为0,则释放p管理的对象的内存。 |
p.unique() | 如果p.use_count()为1,则返回true;否则返回false |
p.use_count() | 返回与p共享对象的智能指针的数量;性能很低,用于调试。 |
上面操作的验证代码
shared_ptr<Test> tsp = make_shared<Test>(11);
cout << tsp.use_count() << endl;//1
//tsp1和tsp指向相同的对象,这个对象的计数器加1
shared_ptr<Test> tsp1(tsp);
cout << tsp.use_count() << endl;//2
//用tsp1改变了对象的data的值,所以用tsp再访问这个对象,发现对象被改变了
tsp1->setData(111);
tsp->fun();//111
shared_ptr<Test> q(new Test(20));
cout << q.use_count() << endl;//1
cout << tsp.use_count() << endl;//2
//如果q不是智能指针,q指向的Test(20)这块内存就泄露了
//q是智能指针,所以自动释放了Test(20)这块内存
q = tsp;
cout << q.use_count() << endl;//3
cout << tsp.use_count() << endl;//3
if(!q.unique()){
cout << "不是只有一个智能指针指向了某个对象" << endl;
}
4. 智能指针作为函数的返回值
shared_ptr<Test> hun(int d){
return make_shared<Test>(d);
}
void use_hun1(int d){
shared_ptr<Test> p = hun(d);
p->fun();
}//p离开作用域后,它指向的内存会被自动释放
shared_ptr<Test> use_hun2(int d){
shared_ptr<Test> p = hun(d);//计数器为1
return p;//返回p时,计数器递增,为2
}//离开作用域后,计数器递减,为1,因为不为0,所以不会释放