unique_ptr
std::unique_ptr
是通过指针占有并管理另一对象,并在 unique_ptr 离开作用域时释放该对象的智能指针。在下列两者之一发生时用关联的删除器释放对象:
- 销毁了管理的
unique_ptr
对象 - 通过
operator=
或reset()
赋值另一指针给管理的unique_ptr
对象。
shared_ptr
std::shared_ptr
是通过指针保持对象共享所有权的智能指针。多个 shared_ptr
对象可占有同一对象。下列情况之一出现时销毁对象并解分配其内存:
- 最后剩下的占有对象的
shared_ptr
被销毁; - 最后剩下的占有对象的
shared_ptr
被通过operator=
或reset()
赋值为另一指针。
每次创建类的新对象时,初始化指针并将引用计数置为1;当对象作为另一对象的副本而创建时,引用计数加1;对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)。
shared_ptr的内存模型:
内存模型下面是用类模板简单实现shared_ptr.
#include <iostream>
using namespace std;
template<typename T>
class SmartPointer {
private:
T* p_;
size_t* count_;
public:
SmartPointer(T* ptr = nullptr) : p_(ptr) {
if (p_) {
count_ = new size_t(1);
}
else {
count_ = new size_t(0);
}
}
SmartPointer(const SmartPointer& ptr) {
p_ = ptr.p_;
count_ = ptr.count_;
(*count_)++;
}
SmartPointer& operator=(const SmartPointer& ptr) {
if (p_ == ptr.p_) {
return *this;
}
if (p_) {
if (--(*count_) == 0) {
delete p_;
delete count_;
}
}
p_ = ptr.p_;
count_ = ptr.count_;
(*count_)++;
return *this;
}
~SmartPointer() {
if (--(*count_) == 0) {
delete p_;
delete count_;
}
}
size_t use_count() {
return *count_;
}
};
int main() {
SmartPointer<int> sp1(new int(10));
SmartPointer<int> sp2(sp1);
SmartPointer<int> sp3(new int(20));
sp2 = sp3;
std::cout << sp1.use_count() << std::endl;
std::cout << sp3.use_count() << std::endl;
}
智能指针带来的性能影响:
1)shared_ptr
的尺寸是裸指针的两倍。
2)会带来控制块的开销。
3)引用计数的递增和递减是原子操作,原子操作一般都比非原子操作慢。
weak_ptr
weak_ptr
是一种不控制对象生命周期的智能指针, 它指向一个 shared_ptr
管理的对象. 进行该对象的内存管理的是那个强引用的 shared_ptr
. weak_ptr
只是提供了对管理对象的一个访问手段。weak_ptr
设计的目的是为配合 shared_ptr
而引入的一种智能指针来协助 shared_ptr
工作, 它只可以从一个 shared_ptr
或另一个 weak_ptr
对象构造, 它的构造和析构不会引起引用记数的增加或减少。weak_ptr
是用来解决shared_ptr
相互引用时的死锁问题,如果说两个shared_ptr
相互引用,那么这两个指针的引用计数永远不可能下降为0,资源永远不会释放。它是对对象的一种弱引用,不会增加对象的引用计数,和shared_ptr
之间可以相互转化,shared_ptr
可以直接赋值给它,它可以通过调用lock函数来获得shared_ptr
。
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class B;
class A
{
public:
weak_ptr<B> pb_;
~A()
{
cout << "A delete\n";
}
};
class B
{
public:
shared_ptr<A> pa_;
~B()
{
cout << "B delete\n";
}
};
void fun()
{
shared_ptr<B> pb(new B());
shared_ptr<A> pa(new A());
pb->pa_ = pa;
pa->pb_ = pb;
cout << pb.use_count() << endl;
cout << pa.use_count() << endl;
}
int main()
{
fun();
return 0;
}
注意的是我们不能通过weak_ptr直接访问对象的方法,比如B对象中有一个方法print(),我们不能这样访问,pa->pb_->print(); 英文pb_是一个weak_ptr,应该先把它转化为shared_ptr,如:shared_ptr p = pa->pb_.lock(); p->print();
参考:
网友评论