事先声明:此篇博客非完全原创
#include <iostream>
#include <memory>
//c++里面的四个智能指针: auto_ptr, shared_ptr, weak_ptr, unique_ptr 其中后三个是c++11支持,并且第一个已经被c++11弃用。
//为什么要使用智能指针:我们知道c++的内存管理是让很多人头疼的事,当我们写一个new语句时,一般就会立即把delete语句直接也写了,
//但是我们不能避免程序还未执行到delete时就跳转了或者在函数中没有执行到最后的delete语句就返回了,
//如果我们不在每一个可能跳转或者返回的语句前释放资源,就会造成内存泄露。
//使用智能指针可以很大程度上的避免这个问题,因为智能指针就是一个类,当超出了类的作用域是,类会自动调用析构函数,析构函数会自动释放资源。
//unique_ptr: 如果内存资源的所有权不需要共享,就应当使用这个(它没有拷贝构造函数),但是它可以转让给另一个unique_ptr(存在move构造函数)。
//shared_ptr: 如果内存资源需要共享,那么使用这个(所以叫这个名字)。
//weak_ptr: 持有被shared_ptr所管理对象的引用,但是不会改变引用计数值。它被用来打破依赖循环(想象在一个tree结构中,父节点通过一个共享所有权的引用(chared_ptr)引用子节点,同时子节点又必须持有父节点的引用。如果这第二个引用也共享所有权,就会导致一个循环,最终两个节点内存都无法释放)。
using namespace std;
void foo(int *p)
{
std::cout << *p << std::endl;
}
void bar(std::shared_ptr<int> p)
{
++(*p);
}
int main()
{
//1. std::unique_ptr
// std::unique_ptr<int> p1(new int(42));
// std::unique_ptr<int> p2 = std::move(p1);// transfer ownership
// //如果你想把对象所有权转移给另一个unique_ptr,需要使用std::move。在所有权转移后,交出所有权的智能指针将为空,get()函数将返回nullptr。
// if(p1)
// foo(p1.get());
// (*p2)++;
// if(p2)
// foo(p2.get());
//2. std::shared_ptr
// std::shared_ptr<int> p1(new int(42));
// auto p3 = std::make_shared<int>(42);//make_shared<T>是一个非成员函数,使用它的好处是可以一次性分配共享对象和智能指针自身的内存。而显示地使用shared_ptr构造函数来构造则至少需要两次内存分配。除了会产生额外的开销,还可能会导致内存泄漏。
// std::shared_ptr<int> p2 = p1;
// bar(p1);
// foo(p2.get());
//3. std::weak_ptr
auto p = std::make_shared<int>(42);
std::weak_ptr<int> wp = p;
auto sp = wp.lock();//注意,你必须调用lock()来获得被引用对象的shared_ptr,通过它才能访问这个对象。如果你试图锁定(lock)一个过期(指被弱引用对象已经被释放)的weak_ptr,那你将获得一个空的shared_ptr.
std::cout << *sp << std::endl;
p.reset();
if(wp.expired())
std::cout << "expired" << std::endl;
return 0;
}