实现原理
C++ 智能指针底层是采用引用计数的方式实现的。简单的理解,智能指针在申请堆内存空间的同时,会为其配备一个整形值(初始值为 1),每当有新对象使用此堆内存时,该整形值 +1;反之,每当使用此堆内存的对象被释放时,该整形值减 1。当堆空间对应的整形值为 0 时,即表明不再有对象使用它,该堆空间就会被释放掉。
有些内存资源已经被释放,但指向它的指针并没有改变指向(成为了野指针),并且后续还在使用;
有些内存资源已经被释放,后期又试图再释放一次(重复释放同一块内存会导致程序运行崩溃);
没有及时释放不再使用的内存资源,造成内存泄漏,程序占用的内存资源越来越多。
c++的垃圾回收机制,便于程序员写出更加安全,便捷的程序,在以上这三种情况下,程序会发生内存溢出,良好的习惯是编写c++代码时候尽可能的使用智能指针代替new去申请空间
shared_str类型(允许多个指针指向同一对象)
std::shared_ptr<T> p1; //不传入任何实参
std::shared_ptr<T> p2(nullptr); //传入空指针 nullptr
std::shared_str<T>=make_shared<T>() //指向T类型的智能指针
拷贝和赋值。拷贝使得对象的引用计数增加1,赋值使得原对象引用计数减1,当计数为0时,自动释放内存。后来指向的对象引用计数加1,指向后来的对象。
unique_str类型(只能有一个指针指向一个给定对象)
虽然我们不能拷贝或者赋值unique_ptr,但是可以通过调用release或reset将指针所有权从一个(非const)unique_ptr转移给另一个unique
//将所有权从p1(指向string Stegosaurus)转移给p2
unique_ptr<string> p2(p1.release());//release将p1置为空
unique_ptr<string>p3(new string("Trex"));
//将所有权从p3转移到p2
p2.reset(p3.release());//reset释放了p2原来指向的内存
weak_ptr
weak_ptr是一种不控制所指向对象生存期的智能指针,它指向一个由shared_ptr管理的对象,将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放,即使有weak_ptr指向对象,对象还是会被释放。
注意智能指针陷阱
不使用相同内置指针初始值初始化多个智能指针
不delete get()返回的指针
不使用get()初始化或reset另一个指针
如果使用get()返回指针,当最后一个对应智能指针销毁后,你的智能指针就无效了