文章目录
- 概念
- 1.shared_ptr
- 1.基本使用
- 2.如何获取原始指针
- 3. 指定删除器
- 2 使用shared_ptr要注意的问题
- 2.1不要用一个原始指针初始化多个shared_ptr
- 2.2. 避免循环引用
- 小结
概念
C++程序设计中使用堆内存是非常频繁的操作,堆内存的申请和释放都由程序员自己管理。内存管理是非常麻烦的,C++11中引入了智能指针的概念,方便管理堆内存。使用普通指针,容易造成堆内存泄露(忘记释放),二次释放,程序发生异常时内存泄露等问题等,使用智能指针能更好的管理堆内存。
智能指针主要包含shared_ptr,unique_ptr,weak_ptr。今天先看看shared_ptr吧。
1.shared_ptr
如下图:
shared_ptr主要包含2个部分,raw_ptr和share_count_object。看下代码示例:
如上图,shared_ptr2个指针都在基类中,ptr就是在堆上创建的裸指针对象,另外一个是计数。
1.基本使用
std::shared_ptr<A> pa(new A());std::cout << "pa.use_count() = " << pa.use_count() << std::endl;std::shared_ptr<A> pb = std::make_shared<A>();std::cout << "pb.use_count() = " << pb.use_count() << std::endl;
2.如何获取原始指针
class B : std::enable_shared_from_this<B>
{
public:virtual ~B(){cout << "delete B\n" << endl;}
};std::shared_ptr<B> pa = std::make_shared<B>();
B* pb = pa.get(); //获取原始指针。
3. 指定删除器
void DeleteIntPtr(int *p) {cout << "call DeleteIntPtr" << endl;delete p;
}//使用
std::shared_ptr<int> p(new int(1), DeleteIntPtr);
std::shared_ptr<int> p2(new int(1), [](int *p) {cout << "call lambda1 delete p" << endl;delete p;
});
std::shared_ptr<int> p3(new int[10], [](int *p) {cout << "call lambda2 delete p" << endl;delete [] p; // 数组删除
});
当p的引用计数为0时,自动调用删除器DeleteIntPtr来释放对象的内存。
2 使用shared_ptr要注意的问题
2.1不要用一个原始指针初始化多个shared_ptr
{int *ptr = new int;shared_ptr<int> p1(ptr);shared_ptr<int> p2(ptr); // 逻辑错误
}
2.2. 避免循环引用
class A {
public:std::shared_ptr<B> bptr;~A() {cout << "A is deleted" << endl;}
};
class B {
public:std::shared_ptr<A> aptr;~B() {cout << "B is deleted" << endl;}
};
使用如下:
{std::shared_ptr<A> ap(new A);std::shared_ptr<B> bp(new B);ap->bptr = bp;bp->aptr = ap;
}
这就是循环引用,要防止出现这种情况,会出现指针释放不掉的。
小结
看完这篇,差不多了,对c++的智能指针有了一定的了解,特别是shared_ptr的各种情况。有兴趣,可以来学习学习。当然,还要注意多看一些官网文档。OK,这篇结束。