shared_ptr(本质是类,表现像指针)
多个指针指向相同对象。
每使用一次,内部计数加1;析构一次,减1,减为0时,自动删除指向的堆内存。
make_shared 初始化指针。
计数器递增:
(1)当用一个shared_ptr初始化另外一个shared_ptr
(2)将它作为参数传递给另外一个函数
(3)作为函数的返回值
计数器递减:
(1)给share_ptr赋新的值
(2)share_ptr被销毁
(3)局部的share_ptr离开作用域
- 注意不要用一个原始指针初始化多个shared_ptr,否则会造成二次释放同一内存
- 注意避免循环引用
#include <iostream>
#include <memory>
int main() {
{
std::shared_ptr<int> ptra = std::make_shared<int>(a);
std::shared_ptr<int> ptra2(ptra); //copy counter+1
std::cout << ptra.use_count() << std::endl;
int b = 20;
int *pb = &a;
std::shared_ptr<int> ptrb = std::make_shared<int>(b);
ptra2 = ptrb; //assign counter-1
pb = ptrb.get(); //获取原始指针
std::cout << ptra.use_count() << std::endl;
std::cout << ptrb.use_count() << std::endl;
std::cout << (*pb) << std::endl;
}
}
运行结果:
2
1
2
20
weak_ptr(配合shared_ptr,旁观者)
可以从一个shared_ptr或者另一个weak_ptr对象构造,获得资源的观测权。
没有指针计数。
use_count() 获取被观测资源(shared_ptr)的引用计数
expired() 判断被观测资源是否存在(true:不存在)
lock() 从shared_ptr获取可用对象
#include <iostream>
#include <memory>
int main() {
{
std::shared_ptr<int> sh_ptr = std::make_shared<int>(10);
std::cout << sh_ptr.use_count() << std::endl;
std::weak_ptr<int> wp(sh_ptr);
std::cout << wp.use_count() << std::endl;
if(!wp.expired()){
std::shared_ptr<int> sh_ptr2 = wp.lock(); //get another shared_ptr
*sh_ptr = 100;
std::cout << wp.use_count() << std::endl;
}
}
//delete memory
}
运行结果:
1
1
2
unique_ptr(唯一拥有其对象)
同一时刻只能有一个unique_ptr指向给定对象(通过禁止拷贝语义、只有移动语义来实现)。
离开作用域时被销毁。
#include <iostream>
#include <memory>
int main() {
{
std::unique_ptr<int> uptr(new int(10)); //绑定动态对象
//std::unique_ptr<int> uptr2 = uptr; //不能賦值
//std::unique_ptr<int> uptr2(uptr); //不能拷貝
std::unique_ptr<int> uptr2 = std::move(uptr); //轉換所有權
uptr2.release(); //释放所有权
}
//超過uptr的作用域,內存釋放
}
使用weak_ptr解决循环引用示例:
#include <iostream>
#include <memory>
class Child;
class Parent;
class Parent {
private:
//std::shared_ptr<Child> ChildPtr;
std::weak_ptr<Child> ChildPtr;
public:
void setChild(std::shared_ptr<Child> child) {
this->ChildPtr = child;
}
void doSomething() {
//new shared_ptr
if (this->ChildPtr.lock()) {
}
}
~Parent() {
}
};
class Child {
private:
std::shared_ptr<Parent> ParentPtr;
public:
void setPartent(std::shared_ptr<Parent> parent) {
this->ParentPtr = parent;
}
void doSomething() {
if (this->ParentPtr.use_count()) {
}
}
~Child() {
}
};
int main() {
std::weak_ptr<Parent> wpp;
std::weak_ptr<Child> wpc;
{
std::shared_ptr<Parent> p(new Parent);
std::shared_ptr<Child> c(new Child);
p->setChild(c);
c->setPartent(p);
wpp = p;
wpc = c;
std::cout << p.use_count() << std::endl; // 2
std::cout << c.use_count() << std::endl; // 1
}
std::cout << wpp.use_count() << std::endl; // 0
std::cout << wpc.use_count() << std::endl; // 0
return 0;
}
参考:
https://www.cnblogs.com/wxquare/p/4759020.html
https://www.cnblogs.com/love-jelly-pig/p/9067843.html