std::unique_ptr:指针ptr的唯一管理者,不能复制赋值,只能通过std::move转移,离开作用域自动销毁对象,实现了*和->操作对象,通过get()获取原始指针
std::shared_ptr:指针ptr的管家,在离开作用域同时引用计数(有多少shared_ptr在引用这个ptr)为零时,销毁管理的对象ptr。
此外还有个重要的特点就是可以共享,就是多个share_ptr对象都保存同一个ptr,共同维护一个共享信息的块(std::make_shared会同时创建一个块存放引用计数等信息,还有一个存放数据对象的内存)。
可以用原始指针构造shared_ptr,每次用这个原始指针构造一个shared_ptr都会分配一个存放引用信息的块,shared_ptr再赋值给shared_ptr会维护同一个块,而如果每个shared_ptr都用原始指针构造,就是每个shared_ptr都有自己的信息块, 这样就会出问题。
管家虽然是管理指针,但最终权利还是在程序手中,原始指针还是可以被随时处置,就会导致各种指针问题,比如上述问题,还有程序中get() 获取后自己delete等,都会造成指针问题,所以还是要注意此类问题,尽量使用std::make_shared构造shared_ptr,这样性能和安全性都有提升,因为一次性分配内存,同时避免原始指针处理
shared_ptr是可以为nullptr的,就是内部的ptr是空的
std::weak_ptr:是为shared_ptr配置的,如果A 内部有一个shared_ptr指向B,B内部有一个shared_ptr指向A,就会在A退出作用域时候,因为B内部还在使用A,所以A在创建时候的数据ptr并不会销毁,引用计数不为0,同样B也是,这样就存在内存泄漏。
还有比如A的一个内部的shared_ptr直接指向了A也是一个意思
这时weak_ptr就开张了,把AB内部的shared_ptr换成weak_ptr就不存在这个问题,weak_ptr只是查看和观察的,不会影响引用计数 ,同时不能直接->调用函数,可以.lock()来返回shared_ptr,也可以用expired()查看使用的shared_ptr的内部数据是否有效(比如已经被销毁)