weak_ptr&unique_ptr

weak_ptr&unique_ptr

weak_ptr

shared_ptr, Binary trees and the problem of Cyclic References

shared_ptr最大的优点是在不再使用的时候,能够自动释放相关的内存,但也存在缺点,就是循环引用——如果两个对象使用shared_ptr相互引用,在对象超出作用域时,就没办法删除内存。

这是因为由于相互引用,引用计数永远不会为0。

Now How to fix this problem?

答案就是使用weak_ptr,weak_ptr能够分享对象,但不会拥有这个对象,它是通过shared_ptr进行创建:

1
2
std::shared_ptr<int> ptr = std::make_shared<int>(4);
std::weak_ptr<int> weakPtr(ptr);

对于weak_ptr对象,我们无法直接使用操作符*和->去访问相关的内存,因此我们只能通过weak_ptr对像去创建shared_ptr,方法是调用lock函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int> ptr = std::make_shared<int>(4);
std::weak_ptr<int> weakPtr(ptr);
std::shared_ptr<int> ptr_2 = weakPtr.lock();
if(ptr_2)
std::cout<<(*ptr_2)<<std::endl;
std::cout<<"Reference Count :: "<<ptr_2.use_count()<<std::endl;
if(weakPtr.expired() == false)
std::cout<<"Not expired yet"<<std::endl;
return 0;
}

如果shared_ptr已经被删除,lock()函数返回空的shared_ptr。

unique_ptr

unique_ptr是c++11提供的智能指针实现之一,用于防止内存泄漏。unique_ptr对象包装了一个原始指针,并负责其生命周期。当该对象被破坏时,然后在其析构函数中删除关联的原始指针。

它跟shared_ptr的用法类似,也能使用原生指针的一些操作符。但不同的是归属权,unique_ptr对象始终是关联的原始指针的唯一所有者。 我们无法复制unique_ptr对象,它只能移动。也因为如吃,其析构函数中不需要任何引用计数,可以直接删除相关的指针。

1
2
3
4
5
6
7
8
// Create a unique_ptr object through raw pointer
std::unique_ptr<Task> taskPtr2(new Task(55));

// Compile Error : unique_ptr object is Not copyable
std::unique_ptr<Task> taskPtr3 = taskPtr2; // Compile error

// Compile Error : unique_ptr object is Not copyable
taskPtr = taskPtr2; //compile error

在unique_ptr类中,拷贝构造函数和赋值构造函数都已经被删除了。

Transfering the ownership of unique_ptr object

虽然不能拷贝一个unique_ptr对象,但我们可以move它们,即传递拥有权。

1
2
std::unique_ptr<Task> taskPtr2(new Task(55));
std::unique_ptr<Task> taskPtr4 = std::move(taskPtr2);

Releasing the associated raw pointer

对unique_ptr对象调用release()函数可以释放相关原始指针的拥有权,即返还一个原始指针。

1
2
std::unique_ptr<Task> taskPtr5(new Task(55));
Task * ptr = taskPtr5.release();